Opção Xargs `-J`

Opção Xargs `-J`

Esse siteapresenta ao xargscomando uma -Jopção que permite passar a entrada padrão para uma posição desejada no argumento do comando:

find . -name '*.ext' -print0 | xargs -J % -0 rsync -aP % user@host:dir/

mas em umPágina de manual do GNU xargsesta opção não está presente.

Qual é a maneira de fazer isso, para comandos que aceitam isso?

Responder1

Não tenho certeza se isso era o que você esperava, mas no mundo BSD (como o macOS) -Ieles -Jdiferem na forma como eles passam as múltiplas "linhas" para o comando. Exemplo:

$ ls
file1 file2 file3

$ find . -type f -print0 | xargs -I % rm %
rm file1
rm file2
rm file3

$ find . -type f -print0 | xargs -J % rm %
rm file1 file2 file3

Assim -I, com xargs executará o comando para cada elemento passado a ele individualmente. Com -J, xargs executará o comando uma vez e concatenará todos os elementos e os passará como argumentos todos juntos.

Alguns comandos, como rmou, mkdirpodem receber vários argumentos e agir sobre eles da mesma maneira, como se você passasse um único argumento e os executasse várias vezes. Mas alguns aplicativos podem mudar dependendo de como você passa os argumentos para eles. Por exemplo o tar. Você pode criar um arquivo tar e adicionar arquivos a ele ou pode criar um arquivo tar adicionando todos os arquivos de uma só vez.

$ find . -iname "*.txt" -or -iname "*.pdf" -print0 | xargs -0 -J % tar cjvf documents.tar.bz2 %

Responder2

Se este for o -Jsinalizador para a versão BSD, xargsnão acredito que exista uma opção equivalente exata para GNU xargs. -Jsubstitui uma única ocorrência dereplstr(por exemplo %) com cada linha chegando através da entrada padrão. A versão GNU possui umsemelhanteopção, porém: -I1 . No entanto, você pode usarreplstrvárias vezes com essa bandeira.

Para casos de uso em que não é importante haver uma ou várias invocações de comando, você poderá usar o GNU xargs -Icomo um substituto imediato. Mas seu exemplo usa rsynce tenho certeza que você não deseja múltiplas invocações disso.

Seu melhor curso de ação é considerar alternativas começando com finde a ação -execou -execdir. Existem duas variações destes. Um é análogo ao GNU -Ie o outro ao BSD -J. Dê uma olhada nesses exemplos...

# Note the escaping of ';'
$ find /tmp -name '*.txt' -exec echo {} \;
/tmp/a.txt
/tmp/b.txt
..
/tmp/z.txt

Agora compare isso com isso:

$ find /tmp -name '*.txt' -exec echo {} +
/tmp/a.txt /tmp/b.txt .. /tmp/z.txt

A única diferença entre os dois é qual "modificador" aparece no final, +ou ;.

1 Outra coisa confusa é que a versão BSD também possui -Ie é semelhante em função a ambos -Je ao GNU -I! Mas isso -Ié afetado por outros sinalizadores e provavelmente não é o que você está procurando.

informação relacionada