xargs substition de mais de um argumento

2

Por padrão, xargs concatenará muitas linhas de sua entrada e passará então para o comando especificado. Por exemplo:

echo -e 'line 1\nline 2\nline 3' | xargs echo 

resulta em

line 1 line 2 line 3

Como os argumentos são enviados para um único comando de eco (dentro dos limites do comprimento da linha de comando).

Às vezes, você deseja usar a string de substituição para colocar os argumentos em outro lugar no comando, em vez do final:

echo -e 'line 1\nline 2\nline 3' | xargs -Ix echo x DONE
line 1 DONE
line 2 DONE
line 3 DONE

Agora, xargs apenas substituiu um argumento por cada chamada de eco, porque, como diz a página man, "-I implica -L 1 ...". Esse é provavelmente o comportamento correto para um caso típico, mas existe alguma maneira de substituí-lo, então eu recebo line 1 line 2 line 3 DONE como saída?

Por favor, note que o meu exemplo é apenas ilustrativo - não estou muito interessado em maneiras não-xargs de abordar esta questão.

    
por BeeOnRope 23.01.2014 / 02:36

3 respostas

2

Eu não sei de uma opção xargs que fará isso, mas você pode conseguir algo semelhante com uma invocação de bash -c :

$ echo -e "line 1\nline    2\nline 3" | xargs bash -c 'echo "${@}" DONE' _
line 1 line 2 line 3 DONE

Observe que xargs não fornece as linhas como argumentos, mesmo se você especificar -L . Você pode querer usar -d para especificar que a nova linha separa itens (apenas gnu xargs, acredito). Compare o seguinte:

$ echo -e "line 1\nline    2\nline 3" |
  xargs bash -c 'printf "<%s>\n" "${@}" DONE' _
<line>
<1>
<line>
<2>
<line>
<3>
<DONE>

$ echo -e "line 1\nline    2\nline 3" |
  xargs -d\n bash -c 'printf "<%s>\n" "${@}" DONE' _
<line 1>
<line    2>
<line 3>
<DONE>
    
por 23.01.2014 / 03:19
1

Converta novas linhas em \nul terminators e use xargs -0

$ echo -ne 'line 1\nline 2\nline 3\n' | tr '\n' '
$ echo -ne 'line 1\nline 2\nline 3\n' | tr '\n' '%pre%' | xargs -0 -Ix echo x DONE
line 1 DONE
line 2 DONE
line 3 DONE
' | xargs -0 -Ix echo x DONE line 1 DONE line 2 DONE line 3 DONE
    
por 23.01.2014 / 07:31
-1

Se eu entendi sua pergunta, acho que você só quer converter novas linhas para um não delimitador.

echo -ne 'foo\nbar\nbaz' | tr '\n' ' ' | xargs -I{} echo {} DONE

    
por 15.07.2015 / 03:47