"o que é que $(ls *.txt)
do"
Resposta curta
$(ls *.txt)
reúne uma lista de nomes de arquivos e e depois os processa . Não não use isso.
Resposta mais longa
-
ls
destina-se a resultados legíveis por humanos. Como um dos mantenedores de ls escreveu em resposta a por quels
não ofereceria uma opção--null
:Se fôssemos fazer isso, então essa é a interface que usaríamos. Contudo
ls
é realmente uma ferramenta para consumo direto de um ser humano e, nesse caso o processamento posterior é menos útil. Para mais processamento,find
(1) é mais adequado. [ênfase adicionada]Em outras palavras, o uso de
ls
para qualquer coisa que não seja a exibição para seres humanos simplesmente não é suportado. Osls
maintainers, por exemplo, recentemente alteraram o formato de saída padrão para algo que, embora fosse mais humano, sem aviso . Portanto, siga os conselhos deles: se você for fazer mais processamento de nomes de arquivos, usefind
em vez dels
. -
$(...)
é a substituição de comando. Uma conseqüência do uso da substituição de comando é que os caracteres de nova linha são removidos. Se o último nome de arquivo na lista contiver novas linhas à direita, elas serão removidas. -
Como
$(...)
não tem aspas duplas, o texto produzido estará sujeito a:-
divisão de palavras
-
Expansão do nome do caminho
O resultado de ambos é mais uma falha nos nomes dos arquivos.
-
-
sem mencionar os problemas com nomes de arquivos que começam com
-
devido à falta de--
(parals
eegrep
, pois oegrep
do Ubuntu é a implementação do GNU que aceita opções mesmo depois de não -option argumentos a menos quePOSIXLY_CORRECT
esteja no ambiente). -
também, se algum desses arquivos
txt
fosse do tipo diretório ,ls
listaria seu conteúdo em vez de eles mesmos. -
e se não houver arquivos
txt
, a saída dels
estará vazia (embora você veja um erro sobre um arquivo*.txt
ausente) e comoegrep
não receberá nenhum argumento de arquivo , ele procurará por Stuff em sua entrada padrão (e aparentemente parará).
Exemplo
Vamos criar 4 arquivos contendo Stuff
em nosso diretório:
$ echo Stuff | tee file1 file2 'a b c.txt' 'f* .txt'
Stuff
$ ls -Q
"a b c.txt" "file1" "file2" "f* .txt"
Agora, vamos executar o comando egrep:
$ egrep "Stuff" $(ls *.txt)
grep: a: No such file or directory
grep: b: No such file or directory
grep: c.txt: No such file or directory
file1:Stuff
file2:Stuff
f* .txt:Stuff
grep: .txt: No such file or directory
Observe que recebemos 4 mensagens de erro sobre arquivos inexistentes. Isso se deve a divisão de palavras . O resultado também mostra correspondências com dois arquivos, file1
e file2
, que não deveriam ter sido pesquisados porque não terminam com .txt
. Isso é devido à expansão do _pathname '.
O comando escrito corretamente produz duas correspondências bem-sucedidas e nenhum erro:
$ egrep -- "Stuff" *.txt
a b c.txt:Stuff
f* .txt:Stuff
Solução recomendada
Uso:
egrep -- "Stuff" *.txt
ou POSIXly:
grep -E -- "Stuff" *.txt
ou:
grep -E -e Stuff -- *.txt
Isso funcionará com qualquer nome de arquivo e não tem nenhuma das limitações da abordagem ls
.