6
votes

BASH Script pour renommer tous les fichiers d'un répertoire?

J'ai un tas de fichiers qui doit être renommé.

file1.txt needs to be renamed to file1_file1.txt
file2.avi needs to be renamed to file2_file2.avi


3 commentaires

Y a-t-il des espaces, des citations, des nouvelles lignes ou d'autres personnages maladroits dans vos noms de fichiers?


Il existe de nombreuses questions précédentes qui sont proches des doublons, y compris Stackoverflow.com/Questtions/1086502/...


Pour plus, voir: Stackoverflow.com/search?q=rename+Files


8 Réponses :


4
votes
recurse() {
 for file in "$1"/*;do
    if [ -d "$file" ];then
        recurse "$file"
    else
        # check for relevant files
        # echo mv "$file" "${file%%.*}_$file"
    fi
 done
}
recurse /path/to/files

4 commentaires

Je pense que vous vouliez dire: pour le fichier dans le fichier *. *; faire mv "$ fichier" `echo" $ {fichier %%. *} _ $ dossier "`; terminé


@Mark, pas beaucoup d'effort Ajout d'un test pour le répertoire.


@ghostDog: Je suis d'accord, l'expansion de Shell est la meilleure façon de faire face aux noms de fichiers pauvres, mais comment proposez-vous de faire cela récursivement dans bash 2.x / 3.x? Parce que votre code ne traverse pas les sous-répertoires.


@Siegex. Vous pouvez faire une récursion purement avec la coquille que j'ai illustré dans mon édition. C'est juste l'idée et non la solution complète, mais vous obtenez le point.



0
votes

J'aime le script de renommant de Perl Cookbook pour cela. Ce n'est peut-être pas / bin / sh mais vous pouvez faire des renommés d'expression réguliers.

La méthode / bin / sh serait d'utiliser SED / CUT / AWK pour modifier chaque nom de fichier à l'intérieur d'une boucle. Si le répertoire est grand, vous auriez besoin de compter sur Xargs.


0 commentaires

-1
votes
#!/bin/bash
# Don't do this like I did:
# files=`ls ${1}`

for file in *.*
do
if [ -f $file ];
then
newname=${file%%.*}_${file}
mv $file $newname
fi
done
This one won't rename sub directories, only regular files.

4 commentaires

jamais Utilisez la sortie de ls pour analyse. Voir MyWiki.woolEdge.org/ParsingLs pour pourquoi c'est


Si vous n'agissez pas pour les noms de fichiers, il est toujours correct d'analyser LS pour les autres champs.


Qu'est-ce que cela signifie $ {fichier %%. *} ?


Bouton @Benjamin: "%%" supprime le patane ". *" À partir de la fin du fichier $.



2
votes
find . -type f | while read FN; do
  BFN=$(basename "$FN")
  NFN=${BFN%.*}_${BFN}
  echo "$BFN -> $NFN"
  mv "$FN" "$NFN"
done

1 commentaires

Cela ne gère pas les noms de fichiers avec des espaces ou des nouvelles lignes neuves. Ne fonctionne pas non plus avec les fichiers des sous-répertoires car il déplace le fichier dans le sous-répertoire dans le répertoire de niveau supérieur.



0
votes

On doit mentionner l'outil mmv , qui est spécialement conçu pour cela.

Il est décrit ici: http: // tldp .Org / LDP / GNU-Linux-Tools-Tools-Sommaire / HTML / Mass-Rename.html

... avec des alternatives.


4 commentaires

Je pense que Askvictor Korma a battu ya là-bas là-bas.


Oui, il était si pressé qu'il n'a pas nommé l'outil principal du groupe. Honnêtement, j'ai trouvé indépendamment le même lien à la recherche de l'outil que j'avais à l'esprit; Et comme je sens que ma réponse est la plus utile, je le quitte.


Pouvez-vous me dire quelle plate-forme a installé MMV par défaut?


Oui: Rock Linux comprend MMV; Mais cela n'aide pas beaucoup parce que c'est une distribution assez obscure. Cependant, Red Hat / Fedora / Centos, Debian / Ubuntu et Gentoo fournissent tous le paquet pour une installation facile.



4
votes

Pour votre cas spécifique, vous souhaitez utiliser MMV code> comme suit:

sudo apt-get install mmv


0 commentaires

0
votes

J'utilise préname (Perl basé), qui est inclus dans diverses distributions Linux. Il fonctionne avec des expressions régulières, afin de dire changer tout img_x.jpg à image_x.jpg que vous feriez xxx

Vous pouvez utiliser l'indicateur -n pour prévisualiser les modifications sans apporter des modifications réelles. < / p>

Entrée de prénom man


0 commentaires

7
votes

Jusqu'à présent toutes les réponses données soit:

  1. nécessite un outil non portable LI>
  2. Se briser horriblement avec des noms de fichiers contenant des espaces ou de nouvelles lignes li>
  3. n'est pas récursif, c'est-à-dire pas ne descend pas dans les sous-répertoires li> ol>

    Ces deux scripts résolvent tous ces problèmes. P>

    BASH 2.x / 3.x H2>
    #!/bin/bash
    
    shopt -s globstar
    for file in ./**; do 
        if [[ -f "$file" ]]; then
            dirname="${file%/*}/"
            basename="${file:${#dirname}}"
            echo mv "$file" "$dirname${basename%.*}_$basename"
        fi
    done
    


7 commentaires

J'ai testé votre solution Bash2.x / 3.x. Exemple de ma sortie -> MV ./file2.txt _./file2.txt


L'utilisation de l'expansion de Shell est toujours la meilleure approche, même pour les nouvelles lignes dans les noms de fichiers


@ Levislevis85: Correction du problème avec le chemin Nom, mais fait travaille avec de nouvelles lignes, c'est juste que le echo vous fait penser autrement.


C'est bien que vous ayez proposé une solution qui fait toutes ces choses ... mais notez que la question a été posée spécifiquement sur les fichiers dans 1 répertoire, sur Linux, sans rien inhabituel sur les noms de fichiers.


@Code Duck: L'ajout de capacités récursives était une tâche triviale et il faut jamais supposer quoi que ce soit sur les noms de fichiers, toujours les traiter comme si elles comprennent des lignes neuves ou d'autres nazés. La seconde que vous n'êtes pas, c'est quand quelqu'un ajoute celui qui brise votre script horriblement et que Dieu sait quoi.


Réponse géniale, Siegex. Ceci est exactement ce que je cherchais.


@karl content de voir une réponse de 14 mois qui aident toujours les gens sortir =)