Comment renommer tous les fichiers avec des caractères spéciaux et des espaces dans un répertoire?

10

Comment puis-je renommer tous les fichiers dans un répertoire spécifique où les fichiers contiennent des espaces vides et des caractères spéciaux ($ et @) dans leurs noms?

J'ai essayé la renamecommande comme suit pour remplacer tous les espaces et caractères spéciaux par un _:

$ ls -lrt
total 464
-rwxr-xr-x. 1 pmautoamtion pmautoamtion 471106 Jul 17 13:14 Bharti Blocked TRX Report Morning$AP@20150716.csv


$ rename -n 's/ |\$|@/_/g' *
$ ls -lrt
total 464
-rwxr-xr-x. 1 pmautoamtion pmautoamtion 471106 Jul 17 13:14 Bharti Blocked TRX Report Morning$AP@20150716.csv
$

La commande fonctionne mais n'apportera aucune modification dans les noms de fichiers et ne renverra pas non plus d'erreur. Comment résoudre ce problème et existe-t-il également d'autres moyens?

Ankit Vashistha
la source
1
Vous vous attendez peut-être à ce que le script de changement de nom perl (ref: manpages.ubuntu.com/manpages/dapper/man1/prename.1.html ), mais obtienne à la place un renommage util-linux, qui ne fonctionne pas de la même manière.
Jeff Schaller

Réponses:

10

Le -ndrapeau est pour

- aucun acte

Aucune action: affichez quels fichiers auraient été renommés.

C'est donc normal si vous n'avez aucun changement.

Concernant votre commande, ça marche pour moi:

$ touch "a @ test"
$ ls
a @ test
$ rename -n 's/ |\$|@/_/g' *
a @ test renamed as a___test

Selon votre coque, vous devrez peut-être échapper

$ rename -n 's/ \|\$\|@/_/g' *

Ou vous pouvez utiliser la […]notation pour regrouper les caractères:

$ rename -n 's/[ @\$]/_/g' *
fredtantini
la source
1
J'ai essayé les trois sans l'option -n et cela ne changera toujours pas le nom du fichier. Je ne donne aucune erreur pour l'un des 3 types mentionnés ci-dessus. Peut-être que la commande renommer ne fonctionne pas pour une raison quelconque. Existe-t-il un autre moyen de modifier tous les fichiers d'un répertoire avec des espaces ou $ ou @ dans leurs noms?
Ankit Vashistha
@AnkitVashistha génère rename -n 's/./_/g' *quelque chose?
fredtantini
Il ne donne rien, aucune sortie, aucune erreur. Il atterrit juste sur la prochaine ligne de commande.
Ankit Vashistha
Rename ne fonctionne pas non plus pour moi pour remplacer (espace) ou ':' sur Ubuntu 18.04, Bash 4.4.20 (1) -release
Ouss
7

Vous pouvez essayer comme ceci:

for file in ./*Block*                                       
do echo mv "$file" "${file//[ ()@$]/_}"
done

Si vous êtes satisfait du résultat, supprimez l' echoavant mvpour renommer les fichiers.

don_crissti
la source
L'une des meilleures solutions que j'ai traversées, j'essayais depuis si longtemps
Sushin Pv
2

à la recherche d'un beau script pour supprimer les caractères spéciaux ainsi que les caractères spéciaux allemands, en les remplaçant par des caractères universels pour ne pas supprimer les informations utiles J'ai mis à jour la dernière version du script qui avait quelques problèmes mineurs entraînant:

#!/bin/bash

for file in ./*
do
  infile=`echo "${file:2}"|sed  \
         -e 's|"\"|"\\"|g' \
         -e 's| |\ |g' -e 's|!|\!|g' \
         -e 's|@|\@|g' -e 's|*|\*|g' \
         -e 's|&|\&|g' -e 's|]|\]|g' \
         -e 's|}|\}|g' -e 's|"|\"|g' \
         -e 's|,|\,|g' -e 's|?|\?|g' \
         -e 's|=|\=|g'  `
  outfileNOSPECIALS=`echo "${file:2}"|sed -e 's|[^A-Za-z0-9._-]|_|g'`
  outfileNOoe=`echo $outfileNOSPECIALS| sed -e 's|ö|oe|g'`
  outfileNOae=`echo $outfileNOoe| sed -e 's|ä|ae|g'`
  outfileNOue=`echo $outfileNOae| sed -e 's|ü|ue|g'`
  outfileNOOE=`echo $outfileNOue| sed -e 's|Ö|OE|g'`
  outfileNOAE=`echo $outfileNOOE| sed -e 's|Ä|AE|g'`
  outfileNOUE=`echo $outfileNOAE| sed -e 's|Ü|UE|g'`
  outfileNOss=`echo $outfileNOUE| sed -e 's|ß|ss|g'`
  outfile=${outfileNOss}
  if [ "$infile" != "${outfile}" ]
  then
        echo "filename changed for " $infile " in " $outfile
        mv "$infile" ${outfile}
  fi
done

exit

résultant en:

entrez la description de l'image ici

@don_crissti: Il fait le hokus-pokus avec l'infile car linux aurait ses propres problèmes avec la gestion des caractères spéciaux lors du déplacement du nom de fichier.

Matthias R. Wiora
la source
1
caractères spéciaux ? lesquels ?
don_crissti
Space, At symbol, Ampersand ....
Matthias R. Wiora
Il n'y a aucun problème à déplacer un fichier avec un nom qui contient des caractères spéciaux (y compris une nouvelle ligne) ... Vous n'êtes probablement pas familier avec les shells (et btw, cela n'a rien à voir avec linux, c'est une fonction shell ... )
don_crissti
mh okay - vous avez peut-être raison
Matthias R. Wiora
1

Étant donné que la renamecommande n'a pas fonctionné pour moi pour des raisons inconnues et que je n'ai pas d'autre réponse à ma question, j'ai moi-même essayé de faire un effort pour rendre le changement de nom possible. Ce n'est peut-être pas la meilleure approche pour renommer les fichiers, mais cela a fonctionné pour moi et c'est pourquoi je voudrais l'afficher comme réponse afin que si quelqu'un d'autre lit cela puisse obtenir de l'aide pour changer les noms de fichiers comme je l'ai fait.

Maintenant pour moi, je sais que tous les fichiers auront un texte spécifique dans leurs noms qui est le mot "Block". Voici les noms des fichiers avant leur changement de nom:

anks@anks:~/anks$ ls -lrt
total 4
-rw-r--r-- 1 anks anks   0 Jul 25 14:47 Bharti TRX Block Report$AP@12Jul15.csv
-rw-r--r-- 1 anks anks   0 Jul 25 14:47 Bharti TRX Block Report$HP@12Jul15.csv
-rw-r--r-- 1 anks anks   0 Jul 25 14:47 Bharti TRX Block Report$CH@12Jul15.csv
-rw-r--r-- 1 anks anks   0 Jul 25 14:47 Bharti TRX Block Report$KK@12Jul15.csv
-rw-r--r-- 1 anks anks   0 Jul 25 14:48 Bharti TRX Block Report$UW@12Jul15.csv

Maintenant, j'ai écrit un petit script shell pour rendre cela possible. Voici le code:

#!/bin/bash

PATH="/home/ebfijjk/anks"

# Put the old filenames in a file.
ls $PATH | grep Block >> oldValues

# Put the new names without " " or "@" or "$" in another file
cat oldValues | sed 's/\$/_/g' | sed 's/\@/_/g' | sed 's/ /_/g' >> newValues

# Create a new file with Old names and New names seperated by a #.
paste -d'#' oldValues newValues >> oldAndNew

# Read the file with both old and new names and rename them with the new names.
while IFS='#'; read oldValue newValue
do
    mv "$oldValue" "$newValue"

done < oldAndNew

rm oldValues newValues oldandNew

Et c'est tout, lorsque j'exécute le script, il renomme tous les noms de fichiers ayant des espaces vides ( ) ou $ou @avec _au lieu de ces caractères.

Ankit Vashistha
la source
vous pouvez remplacer cat foo | sed S1 | sed S2 | sed S3 >> barparsed -e S1 -e S2 -e S3 foo >> bar
Archemar
2
@Archemar - ou simplement sed 's/[ ()@$]/_/g'oused 'y/ ()@$/_____/'
don_crissti
Merci don_crissti et Archemar pour vos commentaires et suggestions.
Ankit Vashistha
1

Celui-ci supprime simplement les caractères spéciaux des noms de fichiers

for file in *; do mv "$file" `echo $file | tr -cd '.A-Za-z0-9_-'` ; done
Námásté Egész-ség.mkv --> NmstEgsz-sg.mkv

mettre echoaprès ; dopour tester avant, comme:

for file in *; do echo mv "$file" `echo $file | tr -cd '.A-Za-z0-9_-'` ; done

Une autre solution:

rename -v 's/[^a-zA-Z0-9\.\s_-]//g' *.* && rename -v 's/[\s]/_/g' *.*
Námásté Egész-ség.mkv --> Nmst_Egsz-sg.mkv

-n possibilité de tester avant.

eapo
la source
0

Je cherche une solution à ce problème depuis un certain temps maintenant. Je travaille sur d'anciens systèmes fermés qui ne peuvent pas avoir de nouveaux packages installés. Je n'ai pas la renamecommande. Enfin, j'ai écrit un script qui semble fonctionner avec tous les caractères spéciaux saisis au clavier. ~@#$%^&*()-_=+[]{}\|;:",<.>?' Le script renommera chaque fichier et répertoire du répertoire courant. Il remplacera tous les caractères spéciaux, sauf -_.par le _caractère. La outfile=ligne peut être modifiée pour utiliser un caractère différent pour le remplacement si vous le souhaitez. Remplacez |_|par |.|pour utiliser le .caractère par exemple.

#!/bin/bash

for file in ./*
do
  infile=`echo "${file:2}"|sed  \
         -e 's|"\"|"\\"|g' \
         -e 's| |\ |g' -e 's|!|\!|g' \
         -e 's|@|\@|g' -e 's|*|\*|g' \
         -e 's|&|\&|g' -e 's|]|\]|g' \
         -e 's|}|\}|g' -e 's|"|\"|g' \
         -e 's|,|\,|g' -e 's|?|\?|g' \
         -e 's|=|\=|g'  `
  outfile=`echo "${file:2}"|sed -e 's|[^A-Za-z0-9._-]|_|g'`
  mv "$infile" ${outfile} &
done

exit
ScriptKitty37
la source
0

Pour moi sur Ubuntu 18.04 LTS avec bash 4.4.20 (1) -release ce one-liner a bien fonctionné pour supprimer les espaces, @,: # ...

Pour tester (notez la echocommande:

for file in ./* ; do if [[ $file == *['!'\ :@#]* ]]; then echo mv "$file" "${file//[ #()@$:]/_}"; fi; done

Éxécuter:

for file in ./* ; do if [[ $file == *['!'\ :@#]* ]]; then echo mv "$file" "${file//[ #()@$:]/_}"; fi; done
Ouss
la source