Sei que não estou respondendo xargs
diretamente à pergunta, mas vale a pena mencionar find
a -exec
opção.
Dado o seguinte sistema de arquivos:
[root@localhost bokeh]# tree --charset assci bands
bands
|-- Dream\ Theater
|-- King's\ X
|-- Megadeth
`-- Rush
0 directories, 4 files
O comando find pode ser feito para lidar com o espaço no Dream Theater e no King's X. Portanto, para encontrar os bateristas de cada banda usando grep:
[root@localhost]# find bands/ -type f -exec grep Drums {} +
bands/Dream Theater:Drums:Mike Mangini
bands/Rush:Drums: Neil Peart
bands/King's X:Drums:Jerry Gaskill
bands/Megadeth:Drums:Dirk Verbeuren
No -exec
opção, {}
está o nome do arquivo, incluindo o caminho. Observe que você não precisa escapá-lo ou colocá-lo entre aspas.
A diferença entre -exec
os terminadores ( +
e\;
) é que +
agrupa quantos nomes de arquivos puderem em uma linha de comando. Considerando que \;
irá executar o comando para cada nome de arquivo.
Assim, find bands/ -type f -exec grep Drums {} +
resultará em:
grep Drums "bands/Dream Theater" "bands/Rush" "bands/King's X" "bands/Megadeth"
e find bands/ -type f -exec grep Drums {} \;
resultará em:
grep Drums "bands/Dream Theater"
grep Drums "bands/Rush"
grep Drums "bands/King's X"
grep Drums "bands/Megadeth"
No caso de grep
tem o efeito colateral de imprimir ou não o nome do arquivo.
[root@localhost bokeh]# find bands/ -type f -exec grep Drums {} \;
Drums:Mike Mangini
Drums: Neil Peart
Drums:Jerry Gaskill
Drums:Dirk Verbeuren
[root@localhost bokeh]# find bands/ -type f -exec grep Drums {} +
bands/Dream Theater:Drums:Mike Mangini
bands/Rush:Drums: Neil Peart
bands/King's X:Drums:Jerry Gaskill
bands/Megadeth:Drums:Dirk Verbeuren
Obviamente, grep
as opções de -h
e -H
controlarão se o nome do arquivo é ou não impresso, independentemente de como grep
é chamado.
xargs
xargs
também pode controlar como os arquivos man estão na linha de comando.
xargs
por padrão, agrupa todos os argumentos em uma linha. Para fazer a mesma coisa que -exec \;
usa xargs -l
. Observe que a -t
opção informa xargs
para imprimir o comando antes de executá-lo.
[root@localhost bokeh]# find ./bands -type f | xargs -d '\n' -l -t grep Drums
grep Drums ./bands/Dream Theater
Drums:Mike Mangini
grep Drums ./bands/Rush
Drums: Neil Peart
grep Drums ./bands/King's X
Drums:Jerry Gaskill
grep Drums ./bands/Megadeth
Drums:Dirk Verbeuren
Veja que o -l
opção diz ao xargs para executar grep para cada nome de arquivo.
Versus o padrão (ou seja, nenhuma -l
opção):
[root@localhost bokeh]# find ./bands -type f | xargs -d '\n' -t grep Drums
grep Drums ./bands/Dream Theater ./bands/Rush ./bands/King's X ./bands/Megadeth
./bands/Dream Theater:Drums:Mike Mangini
./bands/Rush:Drums: Neil Peart
./bands/King's X:Drums:Jerry Gaskill
./bands/Megadeth:Drums:Dirk Verbeuren
xargs
tem melhor controle sobre quantos arquivos podem estar na linha de comando. Dê à -l
opção o número máximo de arquivos por comando.
[root@localhost bokeh]# find ./bands -type f | xargs -d '\n' -l2 -t grep Drums
grep Drums ./bands/Dream Theater ./bands/Rush
./bands/Dream Theater:Drums:Mike Mangini
./bands/Rush:Drums: Neil Peart
grep Drums ./bands/King's X ./bands/Megadeth
./bands/King's X:Drums:Jerry Gaskill
./bands/Megadeth:Drums:Dirk Verbeuren
[root@localhost bokeh]#
Veja que grep
foi executado com dois nomes de arquivos por causa de -l2
.
ls |grep mp3 |sed -n "7p"
você pode apenas usarecho "Lemon Tree.mp3"
.