Je veux renommer le nom du fichier avec son nom de dossier parent, ajout le nom du dossier avant le nom actuel.
par exemple:
Structure de dossier
SOCH NC KT 633-ROYAL BLUE-MULTI
|
| 1.jpg
|
| 2.jpg
|
| 3.jpg
Résultat attendu
SOCH NC KT 633-ROYAL BLUE-MULTI
|
|_SOCH NC KT 633-ROYAL BLUE-MULTI1.jpg
|
|_SOCH NC KT 633-ROYAL BLUE-MULTI2.jpg
|
|_SOCH NC KT 633-ROYAL BLUE-MULTI3.jpg
SOCH NC KT 710-BLACK-MULTI
Quelqu'un pourrait-il indiquer comment cela peut être fait dans un fichier .sh? Existe-t-il un utilitaire disponible pour effectuer l'opération?
Dans un petit script python, renommer des fichiers de manière récursive (dossiers ainsi que sous-dossiers):
#!/usr/bin/env python3
import shutil
import os
import sys
dr = sys.argv[1]
for root, dirs, files in os.walk(dr):
for f in files:
shutil.move(root+"/"+f, root+"/"+root.split("/")[-1]+f)
rename_files.py
Exécutez-le avec le répertoire en argument:
python3 /path/to/rename_files.py /directory/with/files
Comme toujours, essayez d’abord un échantillon!
Le scénario:
Si des fichiers sont trouvés, il divise le chemin d'accès au fichier avec le délimiteur "/", en gardant le dernier dans la ligne (qui est le nom du dossier du parent), à coller avant le nom du fichier:
root.split("/")[-1]
Ensuite, déplacez le fichier vers le fichier renommé:
shutil.move(root+"/"+f, root+"/"+root.split("/")[-1]+f)
Utiliser uniquement Shell (bash
) avec un peu d’aide de mv
:
#!/bin/bash
shopt -s globstar ##globstar will let us match files recursively
files=( /foo/bar/**/*.jpg ) ##Array containing matched files, mention where to search and what files here
for i in "${files[@]}"; do
d="${i%/*}" ##Parameter expansion, gets the path upto the parent directory
d_="${d##*/}" ##gets the name of parent directory
f="${i##*/}" ##gets the file name
echo mv "$i" "$d"/"${d_}""$f" ##renaming, remove echo after confirming what will be changed and you are good
done
Exemple:
$ shopt -s globstar
$ files=( /foo/bar/**/*.jpg )
$ for i in "${files[@]}"; do d="${i%/*}"; d_="${d##*/}"; f="${i##*/}"; echo mv "$i" "$d"/"${d_}""$f"; done
mv /foo/bar/KT/633-ROYAL/4.jpg /foo/bar/KT/633-ROYAL/633-ROYAL4.jpg
mv /foo/bar/KT/633-ROYAL/5.jpg /foo/bar/KT/633-ROYAL/633-ROYAL5.jpg
mv /foo/bar/KT/633-ROYAL/6.jpg /foo/bar/KT/633-ROYAL/633-ROYAL6.jpg
mv /foo/bar/KT/633-ROYAL/BLUE-MULTI/1.jpg /foo/bar/KT/633-ROYAL/BLUE-MULTI/BLUE-MULTI1.jpg
mv /foo/bar/KT/633-ROYAL/BLUE-MULTI/2.jpg /foo/bar/KT/633-ROYAL/BLUE-MULTI/BLUE-MULTI2.jpg
mv /foo/bar/KT/633-ROYAL/BLUE-MULTI/3.jpg /foo/bar/KT/633-ROYAL/BLUE-MULTI/BLUE-MULTI3.jpg
Vous pouvez le faire avec rename
:
rename -n 's/(.*)\//$1\/$1/' */*
Cette commande doit être lancée dans le répertoire directement au-dessus des répertoires que vous souhaitez traiter. Dans un premier temps, il ne listera que les modifications que vous pourrez vérifier, si vous êtes satisfait des résultats, exécutez-le sans -n
pour effectuer le changement de nom.
$ tree
.
└── SOCH NC KT 633-ROYAL BLUE-MULTI
├── 1.jpg
├── 2.jpg
└── 3.jpg
$ rename 's/(.*)\//$1\/$1/' */*
$ tree
.
└── SOCH NC KT 633-ROYAL BLUE-MULTI
├── SOCH NC KT 633-ROYAL BLUE-MULTI1.jpg
├── SOCH NC KT 633-ROYAL BLUE-MULTI2.jpg
└── SOCH NC KT 633-ROYAL BLUE-MULTI3.jpg
rename 's/(.*)\//$1\/$1/' */*
s/a/b/
- s
substituer a
par b
(.*)\/
- prend tout jusqu'au (excl.) La dernière barre en l'enregistrant comme groupe 1 et le remplace par$1\/$1
- groupe 1 (nom de répertoire), une barre oblique et groupe 1 à nouveau (préfixe du nom de fichier)Voici un petit exemple de la façon dont cela peut être fait à partir du répertoire que vous souhaitez modifier.
$> ls
file1.txt file2.txt file3.txt
$> pwd
/home/xieerqi/testing_dir
$> find . -type f -printf "%f\0" | \
> while IFS="" read -d "" filename ; do \
> echo $filename ${PWD##*/}_$filename ; done
file2.txt testing_dir_file2.txt
file1.txt testing_dir_file1.txt
file3.txt testing_dir_file3.txt
Remplacez echo
par mv
ou cp
pour le copier ou le déplacer selon vos besoins
Une autre approche bash seulement, à exécuter dans le dossier où résident les fichiers à renommer:
for f in * ; do mv "$f" "$(basename "$(pwd)")"_"$f" ; done
Cela permettra également de gérer les noms de fichiers et de dossiers avec des espaces.
Solution Bash, exécutée à partir du dossier où sont placés les noms de fichiers que vous souhaitez modifier. Vous devez changer workdir
sur votre chemin
#!/bin/bash
shopt -s globstar
workdir="/path/to/your/dir"
for folder in $workdir/**/*;do
if [[ -d "$folder" ]]; then
for file in "$folder"/*;do
if [[ -f "$file" ]]; then
fi="`basename "$file"`"
fo="`basename "$folder"`"
mv "$file" "$folder/$fo$fi"
fi
done
fi
done
Cela changera tous les fichiers dans tous les répertoires de manière récursive à partir de votre répertoire de travail.