Estou tentando executar o grep em uma lista de algumas centenas de arquivos:
$ head -n 3 <(cat files.txt)
admin.php
ajax/accept.php
ajax/add_note.php
No entanto, mesmo que eu esteja procurando por uma sequência que eu sei que é encontrada nos arquivos, o seguinte não pesquisa os arquivos:
$ grep -i 'foo' <(cat files.txt)
$ grep -i 'foo' admin.php
The foo was found
Eu estou familiarizado com a -f
bandeira que lerá os padrões de um arquivo. Mas como ler os arquivos de entrada ?
Eu tinha considerado a solução horrível de copiar os arquivos para um diretório temporário, pois cp
parece suportar o <(cat files.txt)
formato e, a partir daí, saudar os arquivos. Shirley, há uma maneira melhor.
fonte
while
poderia receber as linhas de file.txt como tal.while
não está recebendo exatamente as linhas do arquivo,read
está fazendo isso;while
apenas nos permite fazer isso em um loop. O loop termina quandoread
falha (ou seja, retorna um código de retorno diferente de zero), normalmente devido ao término do arquivo.IFS= read -r filename
,read filename
é outra coisa.-H
é uma extensão GNU. Você está sentindo falta de alguns--
.supondo que os arquivos estejam em branco ou delimitados por nova linha (onde aspas ou barras invertidas podem ser usadas para escapar desses separadores). Com o GNU,
xargs
você pode especificar o delimitador com-d
(o que desabilita o tratamento de cotação).supondo que os arquivos estejam separados por espaço, tabulação ou nova linha (não há como escapar deles, embora você possa escolher um separador diferente atribuindo-o a
IFS
). Essa falha se a lista de arquivos for muito grande na maioria dos sistemas.Eles também assumem que nenhum dos arquivos é chamado
-
.fonte
$(< file)
vez de$(cat file)
, pelo menos embash
ezsh
.Para ler uma lista de nomes de arquivos do stdin, você pode usar
xargs
. Por exemplo,Por padrão,
xargs
lê itens da entrada padrão, delimitada por espaços em branco. O-d'\n'
comando diz para usar a nova linha como delimitador de argumento, para que ele possa lidar com nomes de arquivos contendo espaços em branco. (Como Stéphane Chazelas aponta, essa é uma extensão do GNU). No entanto, ele não lidará com nomes de arquivos contendo novas linhas; precisaríamos de uma abordagem um pouco mais complicada para lidar com isso.FWIW, essa abordagem é um pouco mais rápida que um
while read
loop, pois oread
comando do bash é muito lento - ele lê seu caractere de dados por caractere, enquantoxargs
lê sua entrada com mais eficiência. Além disso,xargs
apenas chama ogrep
comando quantas vezes for necessário, com cada chamada recebendo vários nomes de arquivos, e isso é mais eficiente do que chamargrep
individualmente para cada nome de arquivo.Consulte a página de manual do xargs e a página de informações do xargs para obter mais detalhes.
fonte
xargs
pode ler itens de um arquivo (como suafiles.txt
lista) com sua opção:Portanto, isso deve funcionar também:
ou para espaços em nomes de arquivos
fonte
Você também pode fazer um for, mas o exemplo do Orion é o mais simples:
(Para cada arquivo listado nos arquivos.txt, execute o comando grep.)
fonte