Iterando sobre padrões glob, não os arquivos neles

3

Eu gostaria de executar as mesmas operações de agregação em cada um dos vários grupos de arquivos em que cada grupo é correspondido por um padrão glob. O que eu não gostaria de fazer é canalizar cada nome de arquivo para a função de agregação separadamente.

Minha primeira tentativa falhou porque os nomes de arquivos foram agrupados no loop externo, nivelando toda a coleção em uma lista simples e não os tratando como lotes separados:

for fileglob in /path/to/bunch*1 /path/to/bunch*2 ... ; do
  stat "$fileglob" | awk [aggregation]
done

Então eu escondi o * do loop escapando dele, depois o escapei para a função:

for fileglob in /path/to/bunch*1 /path/to/bunch*2 ... ; do
  realglob='echo "$fileglob" | sed 's/\//g''
  stat "$realglob" | awk [aggregation]
done

Tem que haver uma maneira melhor. O que é isso?

GNU bash, versão 3.2.51

    
por WAF 31.03.2016 / 22:45

2 respostas

5

Isso requer um uso cuidadoso das citações:

for fileglob in '/path/to/bunch*1' '/path/to/bunch*2' ... ; do
    stat $fileglob | awk [aggregation]
done

Mas isso pode falhar em nomes de arquivos com espaços (ou novas linhas). Melhor usar isso:

fileglobs=("/path/to/bunch*1" "/path/to/bunch*2")

for aglob in "${fileglobs[@]}" ; do
    set -- $aglob
    stat "$@" | awk [aggregation]
done

A glob é expandida corretamente e colocada nos parâmetros posicionais com:

set -- $aglob

Em seguida, cada parâmetro é colocado como um argumento para stat in:

stat "$@"

E a saída de stat vai (como uma saída) para awk .

    
por 01.04.2016 / 00:17
3

Coloque seus padrões globais em aspas simples para evitar que eles sejam interpretados no loop externo.

for fileglob in '/path/to/bunch*1' '/path/to/bunch*2' ; do
stat "$fileglob" | awk [aggregation]
done

Eu não testei isso porque não sei o que você está tentando realizar, mas fiz um teste semelhante.

Sem citações

for a in a* b*; do
echo $a
done

Saída

$ ./test.sh
abc
ade
atlmfc.zip
bce
bin

Com aspas

for a in 'a*' 'b*'; do
echo $a
done

Saída

$ ./test.sh
abc ade atlmfc.zip
bce bin

Basicamente, o glob é interpretado por eco em vez de pelo loop. Assim, existem duas linhas de saída, uma para cada globo.

    
por 31.03.2016 / 23:45