mv
ファイルまたはディレクトリ階層を移動またはコピーすることもできますかcp
?
たとえば、mv
または他の場所 の場合、またはcp
dir1/dir2/file
のみになります。 または も実行したい場合はどうなりますか?ではなく、 を 1 つのコマンドで実行できますか?mv
cp
file
mv
cp
dir1/dir2
mkdir -p dir1/dir2
答え1
cp
のスイッチを使用できます--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
ただし、--parents
スイッチはありませんが、次のようにすることができます。
$ find step1/step2/step3 -name "file" -exec cp --parents {} copy/ \; -delete
それは次のようになります:
- ファイルを見つけます。
- それを(親とともに)宛先にコピーします。
- オリジナルを削除します。
次のような関数を作成できます。
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/
ただし、複数のファイルを移動しようとすると、いくつかの調整が必要になる場合があります。次に例を示します (bash では動作しますが、他のシェルでは保証されません)。
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
}
まあ...予想より少し長いですが、これで十分でしょう
編集:セバスチャン・ピエヒコメントで指摘されているように、cp
to domv
のジョブに頼るのは、本来mv
はコピーファイルを編集する場合は、メタデータを編集するだけです。上記のループを次のように置き換えるとよいでしょう。
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
しかし、これは多くの値については$PWD
、使用する場合には十分注意していただくようお願いいたします。