web-dev-qa-db-fra.com

Renommer des fichiers en ajoutant leur nom de dossier parent

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?

5
Neo

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)

Comment utiliser

  • Copiez le script dans un fichier vide, enregistrez-le sous le nom rename_files.py
  • Exécutez-le avec le répertoire en argument:

    python3 /path/to/rename_files.py /directory/with/files
    

Remarque

Comme toujours, essayez d’abord un échantillon!

Explication

Le scénario:

  • Parcourir les répertoires, rechercher des fichiers.
  • 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)
    
5
Jacob Vlijm

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
3
heemayl

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.

Exemple d'exécution

$ 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

Explication

rename 's/(.*)\//$1\/$1/' */*
  • s/a/b/ - ssubstituer 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)
1
dessert

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

1

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.

0
vanadium

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.

0
EdiD