Kann ich die Verzeichnishierarchie einer Datei auch verschieben oder kopieren, wenn ich die Datei mv
verwende cp
?
Wenn ich beispielsweise mv
oder cp
dir1/dir2/file
anderswo eingebe, wird nur mv
oder angezeigt. Was ist, wenn ich auch oder cp
file
möchte ? Kann dies statt mit einem Befehl erledigt werden?mv
cp
dir1/dir2
mkdir -p dir1/dir2
Antwort1
Sie können cp
den Schalter von verwenden --parents
:
$ mkdir -p step1/step2/step3
$ touch step1/step2/step3/file
$ mkdir copy
$ cp --parents step1/step2/step3/file copy
$ ls copy/step1/step2/step3/file
copy/step1/step2/step3/file
mv
hat allerdings keinen --parents
Schalter, aber Sie könnten etwas tun wie:
$ find step1/step2/step3 -name "file" -exec cp --parents {} copy/ \; -delete
Welches wird:
- Suchen Sie die Datei.
- Kopieren Sie es (zusammen mit seinen Eltern) zum Ziel.
- Löschen Sie das Original.
Sie könnten hierfür eine Funktion erstellen:
mvparents()
{
[[ $# -ne 2 ]] && echo "2 arguments needed." && return
[[ ! -r "$1" ]] && echo "$1 is not readable." && return
[[ ! -d "$2" ]] && mkdir -p "$2"
find $(dirname $1) -name "$(basename $1)" -exec cp --parents {} $2/ \; -delete
}
$ mvparents step1/step2/step3/file copy/
Wenn Sie jedoch mehrere Dateien verschieben möchten, sind möglicherweise einige Anpassungen erforderlich. Hier ist ein Beispiel (funktioniert in Bash, aber keine Garantie für andere Shells):
mvparents()
{
[[ $# -lt 2 ]] && echo "Usage: $0 [source] <source> ... [destination]." && return
# Get the destination directory.
for dest; do true; done
[[ ! -d "$dest" ]] && mkdir -p "$dest"
# Copy the arguments and remove the destination.
parameters=( "$@" )
unset parameters[${#parameters[@]}-1]
# For each source file: find, copy, delete.
for source in "${parameters[@]}"; do
if [ -r "$source" ]; then
find $(dirname $source) -name "$(basename $source)" -exec cp --parents {} $dest/ \; -delete
else
echo "$0: $source is not readable."
fi
done
}
Nun... das ist etwas länger als ich erwartet hatte, aber es sollte funktionieren
Bearbeiten: AlsSebastian Piechin einem Kommentar darauf hingewiesen, dass das Verlassen auf die Arbeit von cp
to do mv
ein ziemlicher Leistungskiller ist, da mv
ursprünglich nichtKopierendie Datei, bearbeiten Sie einfach ihre Metadaten. Sie können die obige Schleife durch Folgendes ersetzen:
for source in "${parameters[@]}"; do
if [ -r "$source" ]; then
[[ ! -d "$dest/$(dirname $source)" ]] && mkdir -p "$dest/$(dirname $source)"
find $(dirname $source) -name "$(basename $source)" -exec mv {} "$dest/$(dirname $source)" \; -delete
else
echo "$0: $source is not readable."
fi
done
Da dieses Ding jedoch auf einemvielzum Wert von $PWD
möchte ich Sie bitten, bei der Verwendung sehr vorsichtig zu sein.