Passando vários parâmetros via xargs

8

Gostaria de poder usar xargs para executar vários parâmetros em diferentes partes de um comando.

Por exemplo, o seguinte:

echo {1..8} | xargs -n2 | xargs -I v1 -I v2 echo the number v1 comes before v2

Espero que retorne

the number 1 comes before 2
the number 3 comes before 4 

... etc

Isso é possível? Eu suspeito que meu uso múltiplo de -I está incorreto.

    
por Damien Sawyer 19.08.2017 / 00:14

3 respostas

17

Acredito que você não pode usar -I dessa maneira. Mas você pode obter o efeito / comportamento que você quer dizendo:

echo {1..8} | xargs -n2 sh -c 'echo "the number $1 comes before $2"' sh

Essencialmente, isso cria um script de shell de uma linha ad hoc , qual xargs executa via sh -c . Os dois valores que xargs analisa da entrada são passados para este "script". O shell então atribui esses valores a $1 e $2 , que você pode referenciar no "script".

    
por 19.08.2017 / 00:33
3

No caso específico de printf , você sempre pode fazer:

echo {1..8} | xargs printf 'the number %s comes before %s\n'

porque printf tem uma habilidade semelhante a xargs intrínseca para executar várias vezes se ele receber mais argumentos do que o necessário para uma única chamada. Embora isso tenha pouca vantagem sobre

printf 'the number %s comes before %s\n' {1..8}

E para listas grandes, o comando simples xargs pode resultar em xargs executando várias instâncias de printf , alguns dos quais podem ter números ímpares de argumentos. Você poderia passar -n 1000 para xargs para se proteger contra isso, onde 1000 é um número par que deve ser pequeno o suficiente para não atingir a lista arg demais limite e grande o suficiente para evitar a execução muitos printf s.

Observe que xargs chamaria, não o printf do seu shell, mas o% externo% co_de, com cada invocação em um novo processo separado.

Observe também que, para uma entrada vazia, exceto em alguns BSDs, ela ainda executaria printf uma vez sem argumento. GNU printf e compatível têm xargs (ou -r ) para evitar isso.

Para ser claro, essa resposta simples é específica para o seu --no-run-if-empty exemplo. e não funcionaria no caso geral onde você deve passar dois parâmetros de cada vez para o seu comando (como seria o caso de printf , por exemplo). Para resolver o problema geral com diff , você pode usar:

for i j ({1..8}) echo the number $i comes before $j
    
por 19.05.2018 / 12:26
2

tente isso:

echo {1..8} |xargs -n 2 bash -c 'echo "the number $0 comes before $1"'
    
por 19.05.2018 / 11:45

Tags