$ ls *mp3 | xargs mplayer
Playing Lemon.
File not found: 'Lemon'
Playing Tree.mp3.
File not found: 'Tree.mp3'
Exiting... (End of file)
Ma commande échoue car le fichier "Lemon Tree.mp3" contient des espaces et donc xargs pense qu'il s'agit de deux fichiers. Puis-je faire fonctionner find + xargs avec des noms de fichiers comme celui-ci?
ls |grep mp3 |sed -n "7p"
vous pouvez simplement utiliserecho "Lemon Tree.mp3"
.Réponses:
La
xargs
commande prend des caractères d'espace blanc (tabulations, espaces, nouvelles lignes) comme délimiteurs. Vous pouvez le réduire uniquement pour les nouveaux caractères de ligne ('\ n') avec une-d
option comme celle-ci:Il ne fonctionne qu'avec les xargs GNU. Pour les systèmes BSD, utilisez l'
-0
option comme ceci:Cette méthode est plus simple et fonctionne également avec les xargs GNU.
la source
-E
, par exemple:xargs -E '\n'
L'utilitaire xargs lit l'espace, la tabulation, la nouvelle ligne et les chaînes délimitées à la fin du fichier à partir de l'entrée standard et exécute l'utilitaire avec les chaînes comme arguments.
Vous voulez éviter d'utiliser l'espace comme délimiteur. Cela peut être fait en modifiant le délimiteur pour xargs. Selon le manuel:
Tel que:
Pour répondre à la question sur la lecture du septième mp3; il est plus simple d'exécuter
la source
find
et GNUxargs
; toutes les versions de ces programmes ne prennent pas en charge ces options (bien qu'il soit nécessaire de le faire).find
avec-print0
etxargs
avec-0
. AFAIK, HP-UX, AIX et Solaris ne le font pas cependant (mais je pense que ce n'est pas le cas: HP-UX 11i non; Solaris 10 non; AIX 5.x non; mais ce ne sont pas des versions actuelles ). Il ne serait pas difficile de changersed
, par exemple, d'utiliser des «lignes» se terminant par'\0'
au lieu de'\n'
, et le POSIX 2008getdelim()
le rendrait facile à gérer.Essayer
au lieu de
la source
xargs sur MacOS n'a pas l'option -d, donc cette solution utilise plutôt -0.
Demandez à ls de générer un fichier par ligne, puis traduisez les sauts de ligne en valeurs nulles et dites à xargs d'utiliser des valeurs nulles comme délimiteur:
ls -1 *mp3 | tr "\n" "\0" | xargs -0 mplayer
la source
Cela a aidé dans mon cas à supprimer différents fichiers avec des espaces. Cela devrait aussi fonctionner avec mplayer. L'astuce nécessaire est les guillemets. (Testé sur Linux Xubuntu 14.04.)
la source
La réponse de Dick.Guertin [1] a suggéré que l'on pourrait échapper aux espaces dans un nom de fichier est une alternative valable aux autres solutions suggérées ici (comme utiliser un caractère nul comme séparateur plutôt que des espaces). Mais cela pourrait être plus simple - vous n'avez pas vraiment besoin d'un personnage unique. Vous pouvez simplement demander à sed d'ajouter directement les espaces échappés:
De plus, le grep n'est nécessaire que si vous ne voulez que des fichiers avec des espaces dans les noms. De manière plus générique (par exemple, lors du traitement d'un lot de fichiers dont certains ont des espaces, d'autres non), il suffit de sauter le grep:
Ensuite, bien sûr, le nom de fichier peut avoir d'autres espaces que des blancs (par exemple, un onglet):
Cela suppose que vous avez un sed qui prend en charge -r (regex étendu) tel que GNU sed ou les versions récentes de bsd sed (par exemple, FreeBSD qui orthographiait à l'origine l'option "-E" avant FreeBSD 8 et prend en charge à la fois -r et -E pour la compatibilité via FreeBSD 11 au moins). Sinon, vous pouvez utiliser une expression de parenthèse de classe de caractères regex de base et entrer manuellement les espaces et les tabulations dans les
[]
délimiteurs.[1] C'est peut-être plus approprié en tant que commentaire ou modification de cette réponse, mais pour le moment je n'ai pas assez de réputation pour commenter et je ne peux que suggérer des modifications. Étant donné que les dernières formes ci-dessus (sans le grep) modifient le comportement de la réponse originale de Dick.Guertin, une modification directe n'est peut-être pas appropriée de toute façon.
la source
ls | grep mp3 | sed -n "7p" | xargs -i mplayer {}
Notez que dans la commande ci-dessus,
xargs
appellera àmplayer
nouveau pour chaque fichier. Cela peut être indésirable pourmplayer
, mais peut être acceptable pour d'autres cibles.la source
mplayer
un nouvel appel pour chaque fichier. C'est important si vous essayez par exemple... | xargs -I{} mplayer -shuffle {}
: cela jouera dans un ordre complètement déterministe, malgré-shuffle
.xargs
est principalement utilisé avec des commandes qui acceptent une liste de noms de fichiers (exemple simple:)rm
, et tente de transmettre autant de noms de fichiers qu'il peut en contenir dans chaque appel, en ne le fractionnant qu'en plusieurs appels si nécessaire. Vous pouvez voir la différence lorsque vous utilisez une commande où chaque appel est visible, commeecho
(par défaut):seq 0 100000 | xargs
imprime tous les nombres de 0 à 23695 (spécifique à la plate-forme, mais c'est ce qui se passe sur mon système) sur la première ligne, à 45539 sur la ligne 2, etc. Et vous avez raison, pour la plupart des commandes, cela n'a pas d'importance.Sur macOS 10.12.x (Sierra), si vous avez des espaces dans les noms de fichiers ou sous-répertoires, vous pouvez utiliser les éléments suivants:
la source
Cela dépend de (a) à quel point vous êtes attaché au numéro 7 par opposition, par exemple, aux citrons, et (b) si l'un de vos noms de fichiers contient des nouvelles lignes (et si vous êtes prêt à les renommer s'ils le font).
Il existe de nombreuses façons d'y faire face, mais certaines d'entre elles sont:
La
read
boucle ne fonctionne pas si les noms de fichiers contiennent des retours à la ligne; les autres fonctionnent correctement même avec des retours à la ligne dans les noms (sans parler des espaces). Pour mon argent, si vous avez des noms de fichiers contenant une nouvelle ligne, vous devez renommer le fichier sans la nouvelle ligne. L'utilisation des guillemets doubles autour du nom de fichier est la clé du bon fonctionnement des boucles.Si vous avez GNU
find
et GNUxargs
(ou FreeBSD (* BSD?), Ou Mac OS X), vous pouvez également utiliser les options-print0
et-0
, comme dans:Cela fonctionne quel que soit le contenu du nom (les deux seuls caractères qui ne peuvent pas apparaître dans un nom de fichier sont la barre oblique et NUL, et la barre oblique ne pose aucun problème dans un chemin de fichier, donc l'utilisation de NUL comme délimiteur de nom couvre tout). Cependant, si vous devez filtrer les 6 premières entrées, vous avez besoin d'un programme qui gère les «lignes» terminées par NUL au lieu de la nouvelle ligne ... et je ne suis pas sûr qu'il y en ait.
Le premier est de loin le plus simple pour le cas spécifique en question; cependant, il peut ne pas se généraliser pour couvrir vos autres scénarios que vous n'avez pas encore répertoriés.
la source
Je sais que je ne réponds pas
xargs
directement à la question, mais cela vaut la peine de mentionnerfind
l'-exec
option de.Étant donné le système de fichiers suivant:
La commande find peut être effectuée pour gérer l'espace dans Dream Theater et King's X. Ainsi, pour trouver les batteurs de chaque groupe à l'aide de grep:
Dans l'
-exec
option{}
représente le nom de fichier, y compris le chemin. Notez que vous n'avez pas à y échapper ou à le mettre entre guillemets.La différence entre
-exec
les terminateurs de (+
et\;
) est qu'il+
regroupe autant de noms de fichiers qu'il peut sur une seule ligne de commande. Tandis que\;
va exécuter la commande pour chaque nom de fichier.Donc, cela
find bands/ -type f -exec grep Drums {} +
se traduira par:et
find bands/ -type f -exec grep Drums {} \;
se traduira par:Dans ce cas,
grep
cela a pour effet secondaire d'imprimer ou non le nom de fichier.Bien sûr,
grep
les options de-h
et-H
contrôleront si le nom de fichier est imprimé ou non, quelle que soit la façon dont ilgrep
est appelé.xargs
xargs
peut également contrôler la façon dont les fichiers man se trouvent sur la ligne de commande.xargs
par défaut regroupe tous les arguments sur une seule ligne. Afin de faire la même chose qui-exec \;
utilisexargs -l
. Notez que l'-t
option indiquexargs
d'imprimer la commande avant de l'exécuter.Vérifiez que l'
-l
option indique à xargs d'exécuter grep pour chaque nom de fichier.Par rapport à la valeur par défaut (c'est-à-dire sans
-l
option):xargs
contrôle mieux le nombre de fichiers sur la ligne de commande. Donnez à l'-l
option le nombre maximum de fichiers par commande.Voir qui a
grep
été exécuté avec deux noms de fichiers à cause de-l2
.la source
Compte tenu du titre spécifique de cet article, voici ma suggestion:
L'idée est de convertir les blancs en n'importe quel caractère unique, comme «<», puis de le changer en «\», une barre oblique inverse suivie d'un blanc. Vous pouvez ensuite diriger cela vers n'importe quelle commande de votre choix, comme:
La clé réside ici dans les commandes «tr» et «sed»; et vous pouvez utiliser n'importe quel caractère à part '<', comme '?' ou même un caractère de tabulation.
la source
tr
? Pourquoi pas justels *.mp3 | sed -n '7!b;s/\([[:space:]]\)/\\\1/g;p'
?Des solutions alternatives peuvent être utiles ...
Vous pouvez également ajouter un caractère nul à la fin de vos lignes à l'aide de Perl, puis utiliser l'
-0
option dans xargs. Contrairement au xargs -d '\ n' (dans la réponse approuvée) - cela fonctionne partout, y compris OS X.Par exemple, pour lister récursivement (exécuter, déplacer, etc.) des fichiers MPEG3 qui peuvent contenir des espaces ou d'autres personnages amusants - j'utiliserais:
(Remarque: pour le filtrage, je préfère la syntaxe "| grep" plus facile à mémoriser aux arguments --name de "find".)
la source