Comment puis-je passer tous les arguments avec xargs en milieu de commande sous linux
Je veux passer tous les fichiers en un seul argument sur Linux, mais je ne suis pas en mesure de le faire.
Ce travail est
ls | sort -n | xargs -i pdftk {} cat output combinewd2.pdf
Cela passe un argument unique par commande, mais je veux en une seule commande.
OriginalL'auteur user2027303 | 2013-02-01
Vous devez vous connecter pour publier un commentaire.
C'est une façon de le faire
ou à l'aide de backtick
Comme l'a souligné dans les commentaires, cela ne fonctionnera pas sur les noms de fichiers contenant des espaces. Dans ce cas, vous pourriez utiliser
eval
Supposons qu'il existe deux fichiers nommés "0 foo" et "1 bar" le résultat de la fonction eval serait la commande désirée, avec les noms de fichier entre guillemets doubles:
Si les noms de fichiers peuvent contenir des sauts de ligne, puis utiliser
find
de commande, voir la discussion par @joeytwiddle dans les commentaires de @andrewdotn de réponse.La solution suivante gère également les noms de fichiers avec des guillemets doubles à l'aide de la
sed
commande d'échapper les guillemets doubles:bash
centrée sur la réponse, mais cool quand même. Cela ne fonctionnera pas danscsh/tcsh
, cependant. (tous les commentaires à propos de shell choix >/dev/null
)Fondamentalement, cela ne fonctionne pas sur les noms de fichiers contenant des espaces. Les mots sont répartis en séparer les arguments.
vous avez raison, je propose une solution en utilisant eval
encore à droite, a ajouté sed commande d'échapper les guillemets doubles
J'ai peur de votre eval solution ne fonctionne pas sur les noms de fichiers contenant des
"
guillemets"
. J'aime la simplicité de votre$(...)
approche pour les moments où nous connaissons les noms de fichiers sont libres de les espaces. J'ai posté une solution comme une réponse distincte.OriginalL'auteur
Utilisation
-I
option:De sortie:
ls
plutôt queecho
que l'entrée, qui est ce que l'OP est en train de faire...OriginalL'auteur
C'est moche, mais vous pouvez l'exécuter
sh -c
et accéder à la liste des arguments passés parxargs
comme"${@}"
, comme suit:L'extra
"${0}"
à la fin est là parce que, comme lesh
de la page de manuel ditPour tester cela, nous allons d'abord créer des fichiers avec des noms qui vont gâcher la plupart des autres solutions:
Tous les arguments sont indiqués correctement. Notez que ceci ne fonctionnera pas si tout les noms de fichiers contiennent des retours à la ligne, et que
ls -v
est fondamentalementls | sort -n
.find . -type f -maxdepth 1 -print0 | sort -zn | xargs -0 sh -c ...
Même si nous sommes à l'aide de
find
alors nous n'avons pas besoinxargs
à tous! Nous pouvons utiliserfind ... -exec [command] {} +
, comme recommandé dans le BashFAQ/020.Yup, utilisez
find
au lieu dels
si il pourrait y avoir des sauts de ligne dans les noms de fichiers.Mais argh, on ne peut pas utiliser les trouver directement dans ce cas, en raison de l'OP, le désir de faire le tri. Par la manière, je pense que le
"$0"
doivent aller à l'intérieur de la coquille de la commande. C'est un étrange caprice desh -c 'foo' bar baz bim
que bar est adoptée comme l' $0 argument, avec machin et bim dans $@, tandis que foo est exécutée. Expérimenter:sh -c 'echo "$0" "$@"' a b c
est à l'extérieur de sorte que le parent
$0
est transmis à l'enfant, mais$@
étend à$1 ...
de xargs. C'est très subtil, c'est pourquoi je mène avec des “C'est moche, mais ...”OriginalL'auteur
Cela doit fonctionner sur les noms de fichiers contenant des espaces, retours à la ligne, les apostrophes et les guillemets (qui sont possibles sur les systèmes de fichiers UNIX):
Que peut-être exagéré par rapport à la accepté de répondre, si vous savez que vous travaillez avec de simples noms de fichiers.
Mais si vous écrivez un script qui sera utilisé à l'avenir, il est souhaitable de ne pas exploser un jour, quand il rencontre inhabituelle (mais valide) entrées.
C'est avant tout une adaptation de andrewdotn's réponse qui met fin à des fichiers d'entrée avec un zéro octet, au lieu de avec un saut de ligne, et donc de préserver les noms de fichiers qui contiennent un ou plusieurs caractères de saut de ligne.
Les options respectives
-print0
,-z
et-0
dire à chacun des programmes d'entrée/sortie doit être délimité par le zéro octet. Trois programmes différents, trois arguments différents!OriginalL'auteur
Le problème ici est que, tandis que xargs pouvez mettre des arguments personnels au moyen de la commande avec
-i
et{}
, il refuse de le faire pour de multiples arguments. Cela semble être une erreur, qui finit par nous causer beaucoup d'ennuis!Hormis les solutions ci-dessus, une autre alternative est d'ajouter simplement les arguments que vous voulez venir après les fichiers à la fin de la liste de fichiers.
Cette approche ne fonctionne pas sur les noms de fichiers contenant des sauts de ligne. Pour que de rares cas, vous devez passer les lignes terminé par un zéro octet de xargs, comme dans mon autre réponse.
OriginalL'auteur
Vous pouvez le faire par l'enchaînement de deux appels à xargs. L'utilisation de la première à la chaîne tous les args ensemble en une seule chaîne et passer un paramètre à
echo
, et la seconde à l'aide de-I
à la place de cette chaîne de args dans l'endroit où vous le voulez, comme suit:OriginalL'auteur
La façon la plus intuitive que j'ai trouvé était de:
Voici un exemple pour renommer des extensions à partir de ".txt" en ".txt.json":
Légèrement avancé exemple pour renommer .txt pour .json (retrait .txt extension)
Une fois, j'ai eu à ajouter la chaîne "Fin de Fichier" pour tous les fichiers.
Si vous le faites à droite, xargs est le roi de toutes les commandes!
OriginalL'auteur