Umbenennen von Dateien mit ihrem Pfadnamen

Umbenennen von Dateien mit ihrem Pfadnamen

Ich habe eine .bdf-Datei in Unterordnern. Alle .bdf-Dateien haben den gleichen Namen: Loads.bdf

Beispiel:

/home/user/folderxx/folderxxx/Load.bdf
/home/user/folderxx/folderxxx/Load.bdf

Ich muss alle Load.bdf-Dateien finden (und in einen neuen Ordner kopieren) und sie mit ihrem Pfadnamen umbenennen.

Beispiel: Nach der gewünschten Operation sollte es ungefähr so ​​aussehen.

folder001_folderAAA_Load.bdf
folder002_folderBBB_Load.bdf

Antwort1

Ich würde dafür das mcpTool aus dem ("Multiple Move")-Paket verwenden :mmv

mcp '/home/user/*/*/Load.bdf' '#1_#2_Load.bdf'

Die #1usw. #2in der zweiten Zeichenfolge werden durch den Inhalt des entsprechenden 1., 2. usw. Platzhalters aus der ersten Zeichenfolge ersetzt. Beachten Sie, dass der Pfad in einfache Anführungszeichen gesetzt ist, sodass die Platzhalter von und mcpnicht von der Shell interpretiert werden.

Mit dem angezeigten Befehl werden die Dateien in das aktuelle Verzeichnis kopiert. Wenn Sie mcpdurch ersetzen mmv, werden die Dateien stattdessen verschoben.

Antwort2

Mit prename( renameauf vielen Systemen als Alias ​​verwendet) ist dies ohne mehrere Durchläufe von mvoder möglich cp:

cd /home/user
find . -type f -name 'Loads.bdf' -exec \
  prename -n 's:^./::; s:/:_:g; s:^:destination/:' {} +

Entfernen Sie es, -nwenn Sie sicher sind, dass die gewünschten Dateien verschoben werden.

Aktualisieren

Um die Dateien zu kopieren, anstatt sie zu verschieben, ist es am schnellsten, sie zuerst mit cpiooder zu kopieren paxund sie dann wie zuvor umzubenennen. Beispiel (mit GNU cpio):

cd /home/user
find . -type f -name 'Loads.bdf | cpio -p --make-directories destination

cd destination
find . -type f -name 'Loads.bdf' -exec  prename -n 's:^./::; s:/:_:g' {} +

Beachten Sie, dass paxes sich zwar sowohl um POSIX als auch um LSB handelt und cpionicht mehr um POSIX. cpioEs handelt sich aber immer noch um das Programm, das auf vielen Systemen häufig zu finden ist.

Um Dateinamen mit Zeilenumbrüchen mit GNU find/ zu verarbeiten cpio, können -print0zu findund -0hinzugefügt werden cpio.

Aktualisierung 2

Die paxLösung ist ein Einzeiler (ohne cd):

cd /home/user
find . -name 'Loads.bdf' | cut -d/ -f 2- | pax -rws ':/:_:g' destination

Oder für jeden Dateinamen (und GNU find):

find /home/user -name 'Loads.bdf' -printf '%P\0' | pax -0rws ':/:_:g' destination

Antwort3

Wenn Sie dies auf einem System tun müssen, das nicht über die in einigen der anderen Antworten genannten Tools verfügt (wie mcp und mmv oder prename), und Sie es vollständig in der Shell tun möchten, können Sie Folgendes tun:

#!/usr/bin/env bash

oldpath="/home/user"
newpath="/home/user/newfolder"

for file in $(find $oldpath -type f -name Load.bdf); do
        shortname=${file#$oldpath/}
        newname="$newpath/${shortname//\//_}"
        if [ -f $newname ]; then
                echo "$newname already exists."
        else
                echo "copy: $file"
                echo "  --> $newname"
                cp $file $newname
        fi
done

Dieses Skript findet alle Load.bdfim oldpathVerzeichnis genannten Dateien, fügt die Verzeichnisnamen zu einem neuen Dateinamen zusammen und kopiert sie in Ihr Zielverzeichnis. Wir können auch prüfen, ob bereits kopierte Dateien vorhanden sind, falls Sie das Skript mehr als einmal ausführen müssen und wir nicht alle Dateien erneut kopieren müssen.

Die resultierende Verzeichnisstruktur würde letztendlich wie folgt aussehen:

bash$ find . -type f
/home/user/folder001/folderAAA/Load.bdf
/home/user/folder002/folderBBB/Load.bdf
/home/user/folder003/folderCCC/Load.bdf
/home/user/newfolder/folder001_folderAAA_Load.bdf
/home/user/newfolder/folder002_folderBBB_Load.bdf
/home/user/newfolder/folder003_folderCCC_Load.bdf

Antwort4

env - sh <<\SCRIPT

    t=/home/user/target f=folder
    cd "${t%/*}" && mkdir -p "$t"
    set -- $f??/$f???/Load.BDF
    while [ -e "$1" ] ; do
        cp "$1" "$t/$(IFS=/
            printf '%s_%s_%s\n' $1)"
    shift ; done

SCRIPT

Ich denke, das ist alles ein vollständig portables Shell-Skript – und es ist ziemlich einfach zu machen, obwohl ich anfangs meine Zweifel hatte.

verwandte Informationen