xargs substitution de plus d'un argument


2

Par défaut xargs concaténera de nombreuses lignes de son entrée et passera ensuite à la commande spécifiée. Par exemple:

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

résulte en

line 1 line 2 line 3

Puisque les arguments sont envoyés à une seule commande echo (dans les limites de la longueur de la ligne de commande).

Parfois, vous souhaitez utiliser une chaîne de remplacement pour placer les arguments ailleurs dans la commande, plutôt que la fin:

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

À présent, xargs n'a substitué qu'un argument à chaque invocation d'écho, car comme le dit la page de manuel "-I implique -L 1 ...". C’est probablement le bon comportement pour un cas typique, mais existe-t-il un moyen de le remplacer, alors je reçois line 1 line 2 line 3 DONE comme sortie?

Veuillez noter que mon exemple est uniquement illustratif - je ne suis pas très intéressé par les moyens non xargs de traiter ce problème.

Réponses:


2

Je ne sais pas d'un xargs option qui le fera, mais vous pouvez obtenir quelque chose de similaire avec une invocation de bash -c:

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

Notez que xargs ne fournit pas le lignes comme arguments, même si vous spécifiez -L. Vous voudrez peut-être utiliser -d pour spécifier que new-line sépare les éléments (gnu xargs uniquement, je crois). Contrastez ce qui suit:

$ 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>

Le bon point sur la façon dont xargs divise les arguments, sur des limites d'espaces, et non de lignes (bien que les lignes soient spéciales pour des arguments tels que -L et donc implicitement pour -I).
BeeOnRope

@BeeOnRope: même avec -L, xargs casse les arguments dans l'espace de mots. Le nombre de lignes spécifie le nombre de lignes contenant des arguments, mais les lignes ne sont pas traitées autrement.
rici

C’est pourquoi j’ai dit "les lignes sont spéciales", non pas que xargs change la façon dont il divise les arguments, mais qu’il utilise les lignes pour répartir initialement les entrées dans les invocations, puis procède à la décomposition habituelle.
BeeOnRope

echo -e "ligne 1 \ n ligne 2 \ n ligne 3" | écho parallèle: {}:
Ole Tange

1

Convertir les nouvelles lignes en \nul terminateurs, puis utilisez xargs -0

$ echo -ne 'line 1\nline 2\nline 3\n' | tr '\n' '\0' | xargs -0 -Ix echo x DONE
line 1 DONE
line 2 DONE
line 3 DONE

Comme ci-dessus, j'ai déjà la même sortie sans les tr et -0 (ce n'est pas nécessaire ici). Le problème est que je veux tout sur une seule ligne: line 1 DONE line 2 DONE ...
BeeOnRope

-1

Si je comprends votre question, je pense que vous voulez simplement convertir les nouvelles lignes en non-délimiteur.

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


Non, je veux que foo, bar et baz soient des arguments uniques. L'exemple est artificiel - le but est de pouvoir mettre quelque chose après les arguments ajoutés par xargs.
BeeOnRope

C'est ce que vous obtiendrez. Par exemple, ls | tr '\n' ' ' | xargs -I{} echo {} DONE les rendements dir1/ dir2/ dir3/ DONE.
user1093043

Non, dans ce cas, la chaîne entière "dir1 / dir2 / dir3 /" est transmise comme un seul argument à echo, ce qui n'est pas ce que je veux. Oui, le résultat est le même dans mon exemple de jouet, mais dans la vraie vie, je ne passe pas à l'écho. Essayez votre exemple en le passant à une version de echo qui cite tous les arguments (par exemple) et vous verrez la différence.
BeeOnRope

Alors ce que vous voulez ne peut pas être fait uniquement avec les options xargs, je ne pense pas. (En outre, même si je vois ce que vous voulez dire maintenant, il n’est pas très clair que c’est ce que vous voulez faire de votre message original, à cause de l’exemple que vous avez inclus).
user1093043
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.