Wie kann ich den Dateinamen nur als Ausgabe des cp-Befehls anzeigen?

Wie kann ich den Dateinamen nur als Ausgabe des cp-Befehls anzeigen?

Ich kopiere Dateien vom Quellordner in den Zielordner mit dem folgenden Befehl:

cp -nv /src/* /dest/ > copy_result.txt

Das Ergebnis der kopierten Dateien ist in der Ausgabedatei wie unten dargestellt:

 « /src/test1.txt » -> « /dest/test1.txt »
 « /src/test2.txt » -> « /dest/test2.txt »

Andernfalls möchte ich, dass die Ausgabedatei nur den Dateinamen ohne den vollständigen Pfad und ohne die Dateierweiterung enthält, etwa so:

test1
test2

Antwort1

Versuchen Sie den Befehl

cp -nv /src/* /dest/ | awk '{print $6}' | rev | cut -d/ -f1 | rev | cut -d. -f1 > copy_result.txt

awkdruckt das sechste Feld. Und revkehrt die Zeichenfolge um. cutteilt die Zeichenfolge an einem durch angegebenen Trennzeichen -dund extrahiert den durch angegebenen Teil -f.

Bearbeiten:
Wie bereits erwähnt, funktioniert dies nicht mit Dateien/Verzeichnissen mit Leerzeichen. Dies funktioniert jedoch, indem Teilzeichenfolgen zwischen '-> « ' und ' »' extrahiert werden:

cp -nv /src/* /dest/ | sed -e 's/.*-> « \(.*\) ».*/\1/' | rev | cut -d/ -f1 | rev | cut -d. -f1 > copy_result.txt

Antwort2

-vist von POSIX nicht spezifiziert. Das bedeutet, dass jede cpImplementierung es anders handhaben kann (oder überhaupt nicht). Wo Ihr cpsagt, « foo »sagt meins 'foo'. Es ist möglich, einen Befehl zu erstellen, der Ihre unerwünschte Ausgabe in die gewünschte umwandelt, dennoch möchte ich eine von der Implementierung unabhängige Lösung präsentieren cp.


Nachdem /src/*Sie Ihren Befehl erweitert haben, cpwerden die resultierenden Einträge nacheinander kopiert. Das bedeutet, dass Sie cp -n /src/* /dest/in

for file in /src/*; do cp -n "$file" /dest/; done

Jetzt ist es einfach, etwas mit zu tun $file. Dadurch wird die gewünschte Ausgabe generiert:

for path in /src/*; do
   file="${path##*/}"
   dst="/dest/$file"
   [ ! -e "$dst" ] && cp "$path" "$dst" && printf '%s\n' "${file%.*}"
done

(Zur Weiterleitung auf „ copy_result.txtVerwenden“ done > copy_result.txtstatt nur done).


Beachten Sie, dass, wenn Sie verwendet haben cp -r -vund mindestens einer der Operanden aus der Erweiterung von /src/*ein Verzeichnis war, cpdessen Inhalt kopiert und gedruckt würde, während der obige Code (nachdem wir hinzugefügt haben -r) genauso viel kopieren, aber nur das Verzeichnis selbst drucken würde. -rist möglicherweise nicht die einzige Option, die zu Diskrepanzen führen würde.

Obwohl der Ansatz unabhängig von cpder Implementierung sein sollte, beruht er darauf, dass einige Optionen nicht verwendet werden. Ein weiterer Nachteil ist, dass der Code cpfür jedes Objekt in einen separaten Prozess ausführt /src/, was alles andere als optimal ist.

Es gibt auch einen Race Condition: Wenn die Datei zwischen und $dsterscheint , wird dies ausgeführt. Sie können verwenden, um das Überschreiben zu vermeiden, die Datei wird aber trotzdem gemeldet.[cpcpcp -nprintf

verwandte Informationen