"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
-
lsdestina-se a resultados legíveis por humanos. Como um dos mantenedores de ls escreveu em resposta a por quelsnã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
lspara qualquer coisa que não seja a exibição para seres humanos simplesmente não é suportado. Oslsmaintainers, 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, usefindem 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--(paralseegrep, pois oegrepdo Ubuntu é a implementação do GNU que aceita opções mesmo depois de não -option argumentos a menos quePOSIXLY_CORRECTesteja no ambiente). -
também, se algum desses arquivos
txtfosse do tipo diretório ,lslistaria seu conteúdo em vez de eles mesmos. -
e se não houver arquivos
txt, a saída delsestará vazia (embora você veja um erro sobre um arquivo*.txtausente) e comoegrepnã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 .