Por que o xargs -I implica -L 1

4

Eu vi Por que 'encontrar - exec cmd {} + 'precisa terminar em' {} + '? , o que explica porque {} + tem que estar no final do -exec cmd (*), e agora eu gostaria de saber por que O GNU xargs é revertido para um comando por argumento de entrada quando você usa -I (ou o reprovado -i ) ... ou como a página do manual o coloca

-I replace-str [...] Implies -x and -L 1.

Por exemplo:

$ seq 1 10 | xargs echo
1 2 3 4 5 6 7 8 9 10
$ seq 1 10 | xargs -I {} echo {}
1
2
3
4
5
6
7
8
9
10

A seção BUGS da página do manual xargs diz apenas:

The -L option is incompatible with the -I option, but perhaps should not be.

e

When you use the -I option, each line read from the input is buffered internally. This means that there is an upper limit on the length of input line that xargs will accept when used with the -I option. To work around this limitation, you can use the -s option to increase the amount of buffer space that xargs uses, and you can also use an extra invocation of xargs to ensure that very long lines do not occur.

Nenhuma das duas explica o motivo.

Um dos principais motivos para usar xargs é reduzir o número de comandos executados (executar um cp ou mv com 1000 nomes de arquivos de origem é melhor do que executar 1000 cp s ou mv s com 1 source filename each) e esta limitação evita que em muitos casos .... a maioria dos casos já que a maioria dos comandos unix quer a fonte (por exemplo, uma lista de arquivos) antes do destino (por exemplo, um diretório).

Então, por que xargs tem essa limitação?

Atualizar 2015-11-05

Eu criei recentemente uma VM freebsd 10.0 e descobri que a versão do freebsd de xargs tem uma opção -J para lidar com esse problema.

-J replstr

If this option is specified, xargs will use the data read from standard input to replace the first occurrence of replstr instead of appending that data after all other arguments. This option will not affect how many arguments will be read from input (-n), or the size of the command(s) xargs will generate (-s). The option just moves where those arguments will be placed in the command(s) that are executed. The replstr must show up as a distinct argument to xargs. It will not be recognized if, for instance, it is in the middle of a quoted string. Furthermore, only the first occurrence of the replstr will be replaced. For example, the following command will copy the list of files and directories which start with an uppercase letter in the current directory to destdir:

/bin/ls -1d [A-Z]* | xargs -J % cp -Rp % destdir

(*) Essencialmente, "porque a especificação POSIX diz isso". IMO, eles deveriam ter tentado com mais afinco encontrar uma solução que permitisse que {} aparecesse em qualquer lugar no -exec ... + , ou pelo menos ferramentas padrão como cp e mv tivessem uma opção como -t do GNU para reverter a origem e o alvo.

    
por cas 03.10.2015 / 02:13

2 respostas

2

(Como isso não responde à pergunta, este deve ter sido um comentário, mas é muito longo - então, trate isso como um comentário).

Como alternativa aos xargs do FreeBSD, você pode usar o GNU Parallel, que não tem essa limitação. Até suporta repetir o contexto:

seq 10 | parallel -Xj1 echo con{}text 
seq 10 | parallel -mj1 echo con{}text 

O GNU Parallel é um paralelizador geral e facilita a execução de trabalhos em paralelo na mesma máquina ou em várias máquinas para as quais você tem acesso ssh. Muitas vezes, pode substituir um loop for .

Se você tem 32 tarefas diferentes que você quer rodar em 4 CPUs, uma forma direta de paralelizar é rodar 8 tarefas em cada processador:

O

GNUParallelgeraumnovoprocessoquandoumtermina-mantendoasCPUsativaseeconomizandotempo:

Instalação

Se o GNU Parallel não for empacotado para sua distribuição, você poderá fazer uma instalação pessoal, que não requer acesso root. Isso pode ser feito em 10 segundos ao fazer isso:

(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash

Para outras opções de instalação, consulte o link

Saiba mais

Veja mais exemplos: link

Assista aos vídeos de introdução: link

Percorra o tutorial: link

Inscreva-se na lista de e-mail para obter suporte: link

    
por 05.07.2016 / 13:14
-2

O POSIX não define as coisas, o POSIX apenas descreve as implementações existentes para se tornar o padrão.

find -exec + foi introduzido em 1989 para o SVr4 por David Korn e dado o fato de que ele foi adicionado muito mais tarde ao padrão, há poucas chances de alterá-lo.

Mas não há problema com o padrão atual, como você sempre pode chamar:

find . -type f -exec sh -c 'somecommand "$@" somedir' sh {} +

Então você vê que não há limitação e não há necessidade de usar opções fora do padrão.

Em relação aos xargs: Você está perguntando sobre internals de uma implementação específica do fornecedor. É óbvio que é muito improvável que você possa obter uma resposta útil à sua pergunta aqui, a menos que o autor da implementação específica do fornecedor esteja lendo e escrevendo aqui.

Meu exemplo, no entanto, também funciona de maneira semelhante para xargs.

    
por 03.10.2015 / 11:48