egrep com o shell script while loop

1

Eu tenho uma lista de arquivos no diretório /tmp/drop . Eu tomei o elemento essencial da minha pergunta em test script zz.sh . Eu peguei uma parte do roteiro e coloquei aqui. Estes são os arquivos e as linhas listadas - e quando é dado ao loop while - como a variável file é atribuída apenas ao nome do arquivo e não às várias outras strings nessas linhas?

Qualquer ajuda seria apreciada e também seria útil para os outros.

machine001:/home/aaa999999> ls -l /tmp/drop | grep "2017-01-29" | egrep  '\.gz$' | tail -10
+ ls -F -l /tmp/drop
+ tail -10
+ grep 2017-01-29
+ egrep \.gz$
-rw-r--r--   1 user1001      user1001           20 Jan 29  2017 pattern101_worker-2_2017-01-29-21:33:13.888.complete.gz
-rw-r--r--   1 user1001      user1001           20 Jan 29  2017 pattern101_worker-2_2017-01-29-21:48:14.632.complete.gz
-rw-r--r--   1 user1001      user1001           20 Jan 29  2017 pattern101_worker-2_2017-01-29-22:03:19.098.complete.gz
-rw-r--r--   1 user1001      user1001           20 Jan 29  2017 pattern101_worker-2_2017-01-29-22:18:19.416.complete.gz
-rw-r--r--   1 user1001      user1001           20 Jan 29  2017 pattern101_worker-2_2017-01-29-22:33:19.878.complete.gz
-rw-r--r--   1 user1001      user1001           20 Jan 29  2017 pattern101_worker-2_2017-01-29-22:48:25.636.complete.gz
-rw-r--r--   1 user1001      user1001           20 Jan 29  2017 pattern101_worker-2_2017-01-29-23:03:26.515.complete.gz
-rw-r--r--   1 user1001      user1001           20 Jan 29  2017 pattern101_worker-2_2017-01-29-23:18:28.279.complete.gz
-rw-r--r--   1 user1001      user1001           20 Jan 29  2017 pattern101_worker-2_2017-01-29-23:33:33.059.complete.gz
-rw-r--r--   1 user1001      user1001           20 Jan 29  2017 pattern101_worker-2_2017-01-29-23:48:33.841.complete.gz
machine001:/home/aaa999999> cat zz.sh
+ cat zz.sh
#!/bin/bash
set -x

DROP_DIR=/tmp/drop
ARCHIVE_DIR=/tmp/arch
YESTERDAY="2017-01-29"
# move from drop dir
ls -1 ${DROP_DIR} | grep ${YESTERDAY} | egrep '\.gz$' | while read file; do
    mv  ${DROP_DIR}/$file ${ARCHIVE_DIR}
        echo 'File name is ' ${file}
done
    
por Venkat M 31.01.2018 / 01:35

3 respostas

2

ls -1 imprime apenas os nomes dos arquivos. ls -l imprime várias outras coisas também. O outro é o número um, o outro uma letra minúscula el.

Embora o -1 seja desnecessário aqui, já que se a saída for redirecionada para um canal, o modo "uma coluna" estará implícito.

Mas, na verdade, você não precisa do ls e do pipe aqui. O loop pode ser substituído por apenas:

for file in "$DROP_DIR/"*"$YESTERDAY"*.gz ; do 
    mv "$file" "$ARCHIVE_DIR"
    echo "File name is ${file#$DROP_DIR/}"
done

Veja também: ParsingLs no wiki do Greg's Bash.

    
por 31.01.2018 / 15:31
0

Sugestão usando o GNU date :

yesterday=$( date -d yesterday +%F )
drop_dir=/tmp/drop
archive_dir=/tmp/arch

mkdir -p "$archive_dir"

mv -f "$drop_dir"/*"$yesterday"*.gz "$archive_dir"

Aqui, "$drop_dir"/*"$yesterday"*.gz será expandido para todos os arquivos correspondentes ao padrão especificado. Isto irá funcionar enquanto o padrão se expandir para vários milhares de caracteres, caso em que o shell irá reclamar com "Argument list too long".

Ou, se você realmente quiser fazer o loop para produzir cada nome de arquivo à medida que eles são movidos (somente o comando mv acima é alterado para o seguinte):

for name in "$drop_dir"/*"$yesterday"*.gz; do
    [ -f "$name" ] || continue
    mv "$name" "$archive_dir"
    printf 'Moved "%s"\n' "$name"
done

Aqui, o loop for iterará os mesmos nomes usados na variação anterior, mas um por um. Cada nome será mantido em $name (que inclui o nome do diretório). Se não houver arquivos correspondentes ao padrão, o padrão permanecerá não expandido. É por isso que fazemos um teste explícito para garantir que $name realmente corresponda a um arquivo existente antes de movê-lo.

Ou com find :

find "$drop_dir" -maxdepth 1 -type f -name "*$yesterday*.gz" \
    -print -exec mv {} "$archive_dir" ';'

Aqui, find selecionará os nomes de $drop_dir que correspondem aos arquivos regulares ( -type f ) e que correspondem ao padrão dado a -name . Para cada um desses nomes, mv é chamado para mover o arquivo para a pasta de destino. Antes de chamar mv , -print listará o nome do arquivo (incluindo o caminho) no terminal.

A opção -maxdepth 1 impede que find recorra a subpastas de $drop_dir .

    
por 19.02.2018 / 15:40
-1

Sua pergunta não é clara para mim, mas acho que o que você parece estar procurando é a opção -o para sua declaração egrep :

 egrep -o "[^[:space:]]+\.gz$"

A opção -o ( --only-matching ) faz com que egrep apenas exiba a parte correspondente das linhas correspondentes. O [^[:space:]] corresponde a qualquer coisa que não seja um caractere de espaço.

    
por 31.01.2018 / 12:28

Tags