bash: ajout d'une chaîne commune aux fichiers contenant des caractères génériques

0

Je me demande s’il existe un moyen de renommer un large éventail de fichiers trouvés à l’aide de modèles génériques. Par exemple, disons que je veux scp tous les fichiers qui correspondent à un certain modèle, mais ajoutent une chaîne aux noms de fichiers à un moment donné. Quelque chose comme ça:

ÉLOIGNÉ:

hello.txt
help.txt
heroes.txt

JE VEUX LOCALEMENT:

hello_copy.txt
help_copy.txt
heroes_copy.txt

Évidemment scp user@remote_host:~/he*.txt ./he*_copy.txt ne fonctionne pas. Je me demande si cela est possible ou si je dois copier chaque fichier individuellement.

Idéalement, je recherche une solution qui fonctionne tout au long de la session, de sorte que je puisse faire la même chose avec mv, cp, etc.

ewok
la source
Je copierais probablement les fichiers dans un répertoire local, le mv les sortir avec le nouveau nom.
mpez0

Réponses:

3

Malheureusement, les wildcards sont assez limités. Mais cela peut être fait avec quelques commandes supplémentaires. Tout d'abord, vous pouvez parcourir les fichiers avec un for:

bash$ ls -1
hello.txt
help.txt
heroes.txt
bash$ for f in *; do echo "$f"; done
hello.txt
help.txt
heroes.txt

Vous pouvez également faire un filtrage initial en utilisant *.txt au lieu de juste *. Assurez-vous de citer la variable pour empêcher les espaces ou les caractères spéciaux dans les noms de fichiers de casser la commande.

Maintenant vous pouvez remplacer une chaîne par une autre avec sed (la barre oblique inverse est nécessaire parce que le point a une signification spéciale sans elle, et le signe dollar après cela signifie "fin de chaîne"):

bash$ for f in *; do echo "$f" | sed s/\.txt$/_copy.txt/; done
hello_copy.txt
help_copy.txt
heroes_copy.txt

Vous pouvez facilement transformer cela en une commande . Par exemple un mv (voyons d’abord comment ça a l'air de faire un extra echo ):

bash$ for f in *; do echo mv "$f" `echo "$f" | sed s/\.txt$/_copy.txt/`; done
mv hello.txt hello_copy.txt
mv help.txt help_copy.txt
mv heroes.txt heroes_copy.txt

Tout semble bon alors faisons-le pour de vrai maintenant:

bash$ for f in *; do mv "$f" `echo "$f" | sed s/\.txt$/_copy.txt/`; done
bash$ ls -1
hello_copy.txt
help_copy.txt
heroes_copy.txt

Vous pouvez même annuler le renommage en utilisant sed s/_copy\.txt$/.txt/ :-)

Antonio Bueno
la source
1
Vous devriez mettre la commande qui ne rompt pas avec les espaces et les caractères spéciaux avant les autres, plutôt que d'en faire un cas spécial. Il y a déjà tellement de scripts shell cassés sur le Web :)
slhck
Tu as raison. Merci pour l'édition :-)
Antonio Bueno