2016-05-24 9 views
-1

Ich dachte, ich würde dies hier herausbringen, um anderen zu helfen, die es brauchen könnten.UNIX: So suchen und kopieren Sie alle Dateien mit dem gleichen Namen in ein anderes Verzeichnis

Ich hatte eine Datei mit dem Namen tabelle.csv, die an 500 verschiedenen Orten auf meinem Server war. Nach ein paar Versuchen habe ich diese Lösung genagelt, um jede Instanz dieser Datei zu kopieren, sie umzubenennen (inkrementell) und sie in einen anderen Ordner zu kopieren.

Hoffe das hilft jemandem!

COUNTER=0; 
for f in $(find folder/ -name 'spreadsheet.csv'); 
do 
    cp -v $f /new/location/spreadsheet$COUNTER.csv; 
    COUNTER=$[$COUNTER+1]; 
done 
+4

Bitte folgen Sie dem Format dieser Website. Stellen Sie das Problem in der Frage und geben Sie die Antwort unten an. – chepner

+0

Beachten Sie, dass die Notation Bash '$ [... arithmetic ...] zugunsten von' $ ((... arithmetic ...)) veraltet ist. 'Or' ((arithmetic ...)) '- siehe [arithmetische Expansion] (https: // www.gnu.org/software/bash/manual/bash.html#Arithmetic-Expansion). Das '$ [...]' mit einzelnen eckigen Klammern ist nicht mehr dokumentiert. –

Antwort

1

Eine einfache bashfor-loop könnte dies erreichen: -

COUNTER="0" 
fileName="spreadsheet.csv" 
for file in $(find folder/ -name "$fileName" -type f -printf '%P\n'); 
do 
    sourcePath=$(dirname $(readlink -f "$file")) 
    cp -v $sourcePath/$fileName /new/location/"$fileName$COUNTER" 
    COUNTER=$((COUNTER+1)) 
done 

Der entscheidende Teil des Skripts den Quellpfad jeder der Dateien wird immer, die ich durch readlink und dirname bin zu erreichen. Verweisen Sie auf ihre man Seiten, um mehr über ihre Beschreibung zu erfahren.

Beispiel: -

$ find . -name "spreadsheet.csv" -type f 
./foo/spreadsheet.csv 
./bar/spreadsheet.csv 
./woo/spreadsheet.csv 
./spreadsheet.csv 

$ ./script.sh 
`/home/dude/foo/spreadsheet.csv' -> `/new/location/spreadsheet.csv0' 
`/home/dude/bar/spreadsheet.csv' -> `/new/location/spreadsheet.csv1' 
`/home/dude/woo/spreadsheet.csv' -> `/new/location/spreadsheet.csv2' 
`/home/dude/spreadsheet.csv' -> `/new/location/spreadsheet.csv3' 
+0

Leerzeichen oder andere spezielle Zeichen in Verzeichnisnamen werden dies brechen: 'mkdir foo \ bar; berühre foo \ bar/speadsheet.csv' –

+0

Ich bin verwirrt über die Sonderfallcodierung für Symlinks.Warum ist es notwendig? Wenn Sie mit "cp" auf den Symlink zugreifen, wird eine Kopie der Datei am Ende des Symlinks erstellt, nicht die Symlink-Informationen kopiert. Also scheint 'readlink' und' dirname' wie Overkill zu funktionieren - das System wird das automatisch ohne weiteres handhaben (also 'cp -v" $ file "" $ new_location/$ fileName $ COUNTER.csv "' würde gut funktionieren Solange Sie 'fileName' in' 'Spreadsheet' 'ändern, da die Nummer vor der' .csv'-Erweiterung stehen muss. –

0

Das Skript brechen wird, wenn es ein Raum oder spezielles Zeichen in mindestens einen Verzeichnisnamen ist.

Inian ist richtig über symlinks auch.

Es gibt unter einer sicheren und Standard-Lösung, bei der nur regulären Dateien durchsucht werden:

find folder/ -type f -name 'spreadsheet.csv' -printf "%p\0" | xargs -0 sh -c ' 
    newlocdir=/new/location; 
    COUNTER=$(ls -1 "${newlocdir}"/spreadsheet*.csv 2>/dev/null | awk "END {print NR}") ; 
    for f ; do 
    cp -v "${f}" "${newlocdir}"/spreadsheet$COUNTER.csv; 
    COUNTER=$(($COUNTER+1)); 
    done' dummyarg0 

-printf "%p\0" druckt Pfadname der mit einer zusätzlichen NULL gefundenen Dateien.

xargs -0 kann die gefundenen Dateien lesen und NULL char als Trennzeichen zwischen den Einträgen betrachten.

| awk "END {print NR}" Gibt die Anzahl der gelesenen Zeilen aus der Pipeline aus.

COUNTER=$(ls -1 "${newlocdir}"/spreadsheet*.csv 2>/dev/null | awk "END {print NR}") speichert die Anzahl der spreadsheet*.csv Dateien, die bereits an der neuen Position vorhanden sind, in COUNTER-Variable.

for f ; do liest die Positionsparameter; die Dateinamen, die von xargs bereitgestellt werden.

sh -c ' .... ' dummyarg0 make sh die angegebenen Befehle ausführen. dummyarg0 ist ein obligatorischer erster Parameter. sh setzt den Wert von Spezialparameter 0 auf dummyarg0 (unbenutzt).

Der Test:

$ find folder/ 
folder/ 
folder/dir2 
folder/dir2/spreadsheet.csv 
folder/foo bar 
folder/foo bar/spreadsheet.csv 
folder/spreadsheet.csv 
folder/tr"uc 
folder/tr"uc/spreadsheet.csv 
folder/fo'o 
folder/fo'o/spreadsheet.csv 
folder/dir1 
folder/dir1/spreadsheet.csv 
$ find folder/ -type f -name 'spreadsheet.csv' -printf "%p\0" | xargs -0 sh -c ' 
    newlocdir=.; 
    COUNTER=$(ls -1 "${newlocdir}"/spreadsheet*.csv 2>/dev/null | awk "END {print NR}") ; 
    for f ; do 
    cp -v "${f}" "${newlocdir}"/spreadsheet$COUNTER.csv; 
    COUNTER=$(($COUNTER+1)); 
    done' dummyarg0 
`folder/dir2/spreadsheet.csv' -> `./spreadsheet0.csv' 
`folder/foo bar/spreadsheet.csv' -> `./spreadsheet1.csv' 
`folder/spreadsheet.csv' -> `./spreadsheet2.csv' 
`folder/tr"uc/spreadsheet.csv' -> `./spreadsheet3.csv' 
`folder/fo\'o/spreadsheet.csv' -> `./spreadsheet4.csv' 
`folder/dir1/spreadsheet.csv' -> `./spreadsheet5.csv' 
Verwandte Themen