bash. mover arquivos, exceto arquivos com um determinado sufixo

4

Existe alguma maneira no bash para glob arquivos que não termina com um certo sufixo?

por exemplo. Eu estou fazendo isso:

mv $ INCDIR / HDR_10_ * $ BACKUPDIR

Mas eu não quero mover o HDR_10_ * que termina com .gz

    
por nos 12.11.2010 / 16:37

3 respostas

4

Isso funcionaria para a movimentação de arquivos:

mv $( echo $INCDIR/HDR_10_* | grep -v '\.gz$') $BACKUPDIR

Você também pediu "para glob arquivos que não terminam com um determinado sufixo?" O Bash tem a opção shell (shopt) extglob, que permite a sintaxe de globbing estendida. O !(...glob...) corresponde a tudo mas ao padrão glob.

shopt -s extglob
cd $INCDIR
mv !(*.gz) $BACKUPDIR

funcionaria somente se $ INCDIR continha apenas arquivos chamados HDR_10_ *, especificamente, ele corresponderia a qualquer arquivo ou diretório em $ INCDIR que não correspondesse a * .gz. Tecnicamente, você está pedindo por um glob que combine com um padrão, mas não com outro, que eu não acho que exista como uma única entidade simples.

    
por 12.11.2010 / 16:51
1

Em ksh, !(*.gz) corresponde a todos os arquivos no diretório atual, exceto os arquivos que correspondem a *.gz . O mesmo padrão funciona no bash após shopt -s extglob e em zsh após setopt ksh_glob . Nem o ksh nem o bash têm uma maneira de obter a intersecção de uma correspondência positiva e negativa. Em zsh, depois de setopt extended_glob , você pode escrever $INCDIR/HDR_10_*~$INCDIR/*.gz .

Uma solução, em qualquer shell estilo Bourne (ash, bash, ksh, zsh, ...), é fazer uma iteração nos arquivos e verificar cada correspondência.

for x in "$INCDIR"/HDR_10_*; do
  case "$x" in
    *.gz) :;;
    *) mv -- "$x" "$BACKUPDIR";;
  esac
done

Outra solução é usar find . O comando a seguir também moverá arquivos em subdiretórios.

find "$INCDIR" -type f -name 'HDR_10_*' \! -name '*.gz' -exec mv {} "$BACKUPDIR" \;

Se você tiver o GNU find (por exemplo, no Linux), você pode adicionar -maxdepth 1 após "$INCDIR" para mover arquivos somente diretamente em $INCDIR .

Observe que você deve sempre usar aspas duplas em torno de substituições de variáveis (por exemplo, "$INCDIR" , não $INCDIR ) , a menos que tenha um bom motivo para omiti-las. Caso contrário, você terá problemas se tiver arquivos cujo nome contenha caracteres especiais, como espaço em branco ou \[?* .

    
por 12.11.2010 / 17:15
1

Se você usar find , grep e xargs , poderá fazer isso com bastante facilidade.

Tenho certeza de que existem construções melhores, mas isso é algo que vem à mente imediatamente:

# find <here>| <pattern>    | <notpattern>| <what to do>
find $INCDIR | grep HDR_10_ | grep -v .gz | xargs mv $BACKUPDIR

Uma correção foi apontada nos comentários de que a tentativa rápida acima não funcionará porque mv não está recebendo seus argumentos na ordem correta de xargs :

find $INCDIR -name 'HDR_10_*' ! -name '*.gz' -exec mv {} $BACKUPDIR \
    
por 12.11.2010 / 16:42

Tags