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
awk
druckt das sechste Feld. Und rev
kehrt die Zeichenfolge um. cut
teilt die Zeichenfolge an einem durch angegebenen Trennzeichen -d
und 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
-v
ist von POSIX nicht spezifiziert. Das bedeutet, dass jede cp
Implementierung es anders handhaben kann (oder überhaupt nicht). Wo Ihr cp
sagt, « 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, cp
werden 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.txt
Verwenden“ done > copy_result.txt
statt nur done
).
Beachten Sie, dass, wenn Sie verwendet haben cp -r -v
und mindestens einer der Operanden aus der Erweiterung von /src/*
ein Verzeichnis war, cp
dessen 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. -r
ist möglicherweise nicht die einzige Option, die zu Diskrepanzen führen würde.
Obwohl der Ansatz unabhängig von cp
der Implementierung sein sollte, beruht er darauf, dass einige Optionen nicht verwendet werden. Ein weiterer Nachteil ist, dass der Code cp
fü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 $dst
erscheint , wird dies ausgeführt. Sie können verwenden, um das Überschreiben zu vermeiden, die Datei wird aber trotzdem gemeldet.[
cp
cp
cp -n
printf