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 mcp
Tool aus dem ("Multiple Move")-Paket verwenden :mmv
mcp '/home/user/*/*/Load.bdf' '#1_#2_Load.bdf'
Die #1
usw. #2
in 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 mcp
nicht von der Shell interpretiert werden.
Mit dem angezeigten Befehl werden die Dateien in das aktuelle Verzeichnis kopiert. Wenn Sie mcp
durch ersetzen mmv
, werden die Dateien stattdessen verschoben.
Antwort2
Mit prename
( rename
auf vielen Systemen als Alias verwendet) ist dies ohne mehrere Durchläufe von mv
oder möglich cp
:
cd /home/user
find . -type f -name 'Loads.bdf' -exec \
prename -n 's:^./::; s:/:_:g; s:^:destination/:' {} +
Entfernen Sie es, -n
wenn 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 cpio
oder zu kopieren pax
und 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 pax
es sich zwar sowohl um POSIX als auch um LSB handelt und cpio
nicht mehr um POSIX. cpio
Es 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 -print0
zu find
und -0
hinzugefügt werden cpio
.
Aktualisierung 2
Die pax
Lö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.bdf
im oldpath
Verzeichnis 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.