GNU/Linux >> Tutoriels Linux >  >> Linux

Comment utiliser des caractères génériques dans une commande xargs ?

Vous étiez très proche.

seq 15 -1 1 | xargs [email protected] sh -c 'mv @_* @'

Vous devez retarder l'interprétation (expansion) du * jusqu'après le @ substitution a eu lieu. (Mais vous avez déjà compris que c'était ça le problème, n'est-ce pas ?)

On m'a conseillé de ne jamais intégrer un nom de fichier inconnu (ou une autre chaîne de substitution) directement dans une ligne de commande shell. L'exemple ci-dessus est probablement assez sûr, car vous savez quelles seront les chaînes —15 , 14 , …, 3 , 2 et 1 . Mais utiliser l'exemple ci-dessus comme modèle pour des commandes plus complexes peut être dangereux. Un arrangement plus sûr serait

seq 15 -1 1 | xargs [email protected] sh -c 'mv -- "$1"_* "$1"' x-sh @

x-sh est une chaîne semi-arbitraire qui sera utilisée pour étiqueter tous les messages d'erreur émis par le shell invoqué. Ceci est équivalent à mon premier exemple, sauf que plutôt que d'intégrer les chaînes (représentées par @ ) directement dans la commande shell, il les injecte en fournissant le @ en tant qu'argument du shell, puis en les référençant en tant que "$1" .

PS Vous avez suggéré d'exécuter le seq commande en sens inverse(seq 15 -1 1 , qui génère 15 , 14 , …, 3 , 2 , 1 plutôt que 1 , 2 , 3 , …, 14 , 15 ) et personne ne l'a mentionné. Ce serait une partie importante de la réponse si vos noms de fichiers étaient comme 1foo.txt , 2bar.asc , et 13test.png , etc. (avec différents caractères apparaissant après le nombre, plutôt que toujours _ ). Dans ce cas, la commande serait mv "$1"* "$1" (sans le _ ), et, si vous avez fait 1 d'abord, puis la commande mv 1* 1 balayerait tous les 10quick* , 11brown* , 12fox* , etc., fichiers, avec le 1foo* des dossiers. Mais

seq 1 15 | xargs [email protected] sh -c 'mv -- "$1"_* "$1"' x-sh @

devrait être sûr.

P.P.S. Le seq La commande n'est pas spécifiée par POSIX. L'expansion de l'accolade n'est pas non plus dans la coque. Une solution compatible POSIX peut être construite en combinant la réponse de Grawity à cette question avec cette autre réponse d'Adam Katz :

i=1
while [ "$i" -le 15 ]
do
    mv -- "${i}"_* "$i"
    i=$((i+1))
done

P.P.P.S. Ce n'est pas critique lorsque vous savez que les noms de fichiers commencent par des caractères alphanumériques (c'est-à-dire des lettres et des chiffres), mais, dans des cas plus généraux, vous devez utiliser -- entre le nom de la commande et les arguments. Cela améliore la gestion des noms de fichiers commençant par un tiret. Le -- indique à la commande de traiter l'argument (le nom du fichier)comme un argument. Sans cela, un tel argument pourrait être traité comme une chaîne d'option.


N'utilisez simplement pas xargs pour ça. Utiliser un for boucle :

for i in $(seq 1 15); do
    mv ${i}_* $i
done

Encore mieux est d'utiliser l'expansion des accolades au lieu de seq :

mkdir {1..15}

for i in {1..15}; do
    mv ${i}_* $i
done

Linux
  1. Comment utiliser BusyBox sous Linux

  2. Comment utiliser les commandes d'historique de Bash

  3. Comment j'utilise cron sous Linux

  4. Comment utiliser FIND sous Linux

  5. Comment utiliser Nginx pour rediriger

Comment utiliser la commande Linux nohup

Comment utiliser traceroute sur Kali Linux

Comment utiliser Instagram dans le terminal

Comment utiliser la commande PS

Comment utiliser la commande TOP

Comment utiliser FTP