Apenas selecione diretórios e ordene de maneira específica com echo

3

Eu não tenho experiência no ambiente Unix e tenho que ajustar um script. Eu acho que isso é um conhecimento básico, mas eu não consegui encontrar uma solução simples pesquisando isso.

O script obtém todos os webappsrv em um diretório para reiniciá-los:

TMPLIST='cd $MYWEBAPPSRV_DIR; /bin/echo *'

Então, isso retorna uma lista como esta:

myAppSrv_1
myAppSrv_11
myAppSrv_12
myAppSrv_2
myAppSrv_3
...
myApSrv_9
somescript
somemorescriptfiles

Como eu excluo os arquivos de script e seleciono apenas os diretórios desejados? E como posso alterar a ordem de forma simples, porque os servidores precisam ser reiniciados por ordem numérica (1, 2, 3, ..., 11, 12)? Não consigo renomear os diretórios. Eu sei que seria possível dividir os diretórios em texto e partes numéricas e, em seguida, reordenar pela parte numérica, mas existe uma opção mais simples, como um parâmetro de classificação especial?

    
por kl78 13.01.2017 / 09:48

5 respostas

2

altere assim e tente

TMPLIST='cd $MYWEBAPPSRV_DIR; ls -l | awk '/myApp/{print $NF}' | sort -t_ -n -k2'

TMPLIST='cd $MYWEBAPPSRV_DIR; ls -1 | awk '/myApp/' | sort -t_ -n -k2'
    
por 13.01.2017 / 09:55
3
O

Zsh está disponível na maioria das distribuições, mas geralmente não faz parte da instalação padrão. Se a instalação não for um problema, use-a, pois seu recurso qualifier resolve seu problema muito facilmente:

#!/bin/zsh
cd $MYWEBAPPSRV_DIR
TMPLIST=(*(/n))
for app in $TMPLIST; do … done

O glob * lista todos os arquivos (exceto arquivos de pontos), em seguida, o qualificador de glob / seleciona apenas os que são diretórios e n causa a classificação numérica para sequências de dígitos em vez da ordem lexicográfica padrão. Se você não quiser mudar para o diretório, mas quiser excluir a parte do diretório das correspondências, use um modificador de expansão de histórico para manter apenas a parte do nome base:

#!/bin/zsh
TMPLIST=($MYWEBAPPSRV_DIR/*(/n:t))
for app in $TMPLIST; do … done

Se a instalação do zsh não for prática e você estiver executando um sistema com GNU coreutils (por exemplo, Linux não integrado, Cygwin) e os nomes de arquivo não contiverem caracteres especiais (espaço em branco ou curingas), você poderá usar ls -v para classificar nomes de arquivos com ordem numérica para sequências de dígitos e -F para mostrar tipos de arquivos combinados com um filtro de texto para selecionar apenas diretórios.

TMPLIST=$(ls -Fv $MYWEBAPPSRV_DIR | sed -n 's!/$!!p')
for app in $TMPLIST; do … done
    
por 13.01.2017 / 20:52
2
for (( n = 1; n < 12; ++n )); do
    for appsrv_dir in "$MYWEBAPPSRV_DIR"/*_"$n"; do
        if [[ -d "$appsrv_dir" ]]; then
             ( cd "$appsrv_dir" && somecommand )
        fi
    done
done

Isso itera pelos números de 1 a 12 e corresponde a qualquer coisa no diretório $MYWEBAPPSRV_DIR que tenha esse número no final do nome (com um sublinhado antes dele). Se é um diretório, faça o que você precisa fazer com ele. Essa sintaxe requer bash ou ksh .

"12" deve obviamente ser o maior sufixo numérico de qualquer diretório em $MYWEBAPPSRV_DIR .

Outra maneira de fazer isso, com a ordenação explícita dos nomes dos diretórios: Primeiro, faça a lista de diretórios:

for thing in "$MYWEBAPPSRV_DIR"/*_[0-9] "$MYWEBAPPSRV_DIR"/*_[0-9][0-9]
do
    if [[ -d "$thing" ]]; then
      printf '%s\n' "$thing"
    fi
done

Isso passa por tudo no diretório $MYWEBAPPSRV_DIR que tem um nome de arquivo terminando com _ seguido por um ou dois dígitos e envia esses nomes para a saída padrão se eles forem nomes de diretórios.

Em seguida, classifique esses nomes com base no número após _ :

for thing in "$MYWEBAPPSRV_DIR"/*_[0-9] "$MYWEBAPPSRV_DIR"/*_[0-9][0-9]
do
    if [[ -d "$thing" ]]; then
      printf '%s\n' "$thing"
    fi
done | sort -t '_' -k2,2n

Supondo que haja apenas um sublinhado no nome, isso classificará os nomes em ordem numérica crescente com base no número do sufixo. O utilitário sort lê a entrada padrão e grava a lista classificada de diretórios na saída padrão.

Depois, faça o que você precisa fazer com esses diretórios:

for thing in "$MYWEBAPPSRV_DIR"/*_[0-9] "$MYWEBAPPSRV_DIR"/*_[0-9][0-9]
do
    if [[ -d "$thing" ]]; then
      printf '%s\n' "$thing"
    fi
done | sort -t '_' -k2,2n |
while read appsrv_subdir; do
    ( cd "$MYWEBAPPSRV_DIR/$appsrv_subdir" && somecommand )
done
    
por 13.01.2017 / 11:41
1

Se você não precisar excluir nenhum dos diretórios, também poderá fazê-lo:

ls -d */ | sort -t_ -n -k2
    
por 13.01.2017 / 10:08
1

Para ordenar as entradas por ordem numérica adequada (por exemplo, 1, 2, 3, [...], 9, 10, 11, 12) em vez de ordenação de caracteres (por exemplo, 1, 10, 11, 12, 2, 3, [...], 9) você pode usar o comando ls com a opção -v e imprimir um por linha com a opção -1 .

Altere seu comando para TMPLIST="$(ls -v1 $MYWEBAPPSRV_DIR)" para criar uma lista com todos os arquivos na ordem correta.

Não sei exatamente o que você quer dizer quando diz que quer apenas um diretório, não um arquivo. Se eu entendi mal, por favor, esclareça. Aqui está um script que, dado um caminho, executará algum código se for um arquivo ou código diferente se for um diretório. Armazene o caminho a ser verificado em uma variável chamada $ test para que isso funcione.

if [ "$(ls -ld $test | grep '^d')" != "" ]
then echo "Directory code here"
else echo "File code here"
fi
    
por 13.01.2017 / 10:39