Renommer une série de fichiers
Question
Essayer de renommer une série de fichiers sur un serveur Linux. Il est facile de trouver les fichiers que je veux:
find . -type f -wholename \*.mbox
Bien sûr, étant des fichiers mbox, certains d’entre eux ont des espaces dans les noms, donc ça devient:
find . -type f -wholename \*.mbox -print0
Je suis en train d'exécuter xargs pour pouvoir renommer les fichiers:
find . -type f -wholename \*.mbox -print0 | xargs -0 -I{} echo ${"{}"/.mbox/}
L'écho devrait renvoyer quelque chose comme INBOX, étant donné INBOX.mbox, cependant, se plaindre bash:
bash: ${"{}"/.mbox/}: bad substitution
Comment puis-je résoudre ce problème? J'aimerais essayer de le conserver si possible dans une solution find / xargs, afin que je n’ajoute pas beaucoup de constructions en boucle autour de celle-ci.
La solution
Essayez
find . -type f -wholename \*.mbox | sed 's/\(.*\)\.mbox/mv "\1.mbox" "\1"/' | sh
Ce n'est pas une preuve à 100% si certains fichiers contiennent des guillemets, mais je suppose que vous pouvez l'ignorer:)
Autres conseils
Parallèle GNU http://www.gnu.org/software/parallel/ a {.} qui supprime l'extension:
find . -type f -wholename \*.mbox -print0 | parallel -0 mv {} {.}
Si vous savez que les noms de fichiers ne contiennent pas \ n, cela fonctionnera également:
find . -type f -wholename \*.mbox | parallel mv {} {.}
Je pense que vous avez besoin de ceci:
find . -wholename \*.mbox | awk '{new=<*>; gsub("\.mbox<*>quot;, "", new) ; system("mv \"" <*> "\" \"" new "\"") }'
(devrait être compatible avec gawk et mawk, testé sur mawk). Il n'utilise pas xargs, mais notez qu'il ne crée pas de nouveau processus pour chaque fichier déplacé. Si vous devez déplacer une grande quantité de fichiers, vous remarquerez l’avantage. Warrning: si l'un des fichiers contient une nouvelle ligne dans son nom, vous aurez des problèmes (mais s'il s'agit d'un problème, que Dieu soit avec vous).
Vous améliorez encore cette solution en utilisant xargs pour supprimer plusieurs fichiers lors d'une seule invocation rm
.
Si vous avez vraiment besoin de rapidité, je suggérerais que vous utilisiez un script python au lieu de awk. Cela fera tous les rm
sans un fork.
Pourriez-vous utiliser renommer (1)? Il vient avec perl.
Vous pouvez essayer:
find . -type f -wholename \*.mbox -print0 | sed 's/\.mbox//'
Votre problème est d’essayer de vous connecter à xargs. À ce stade, " {} &
ne veut rien dire.
Pour renommer les fichiers (en supposant que vous êtes sous bash)
find . -type f -wholename \*.mbox -print0 | \
while read I ; do
mv $I $(echo $I | sed 's/\.mbox//') ;
done ;
Voilà, ça devrait faire l'affaire ....
# find .
.
./test.tst
./test1.tst
./test2.tst
./test/test4.tst
./test/test5.tst
#
for file in `find . -type f`
do
mv $file ${file%.tst}.new
done
# find .
.
./test
./test/test4.new
./test/test5.new
./test1.new
./test2.new