ディレクトリを巡回しながらサブディレクトリを探し、特定のファイルを探して他の場所にコピーしています。以下を行っています。
for i in `ls ./*/filename`; do cp $i ../test2; done
これは、すべてのファイル名を取得してtest2ディレクトリに移動します...問題は、ソースディレクトリ名も必要であるということです。
for i in `ls ./dirname/filename`; do cp ../test2/dirname/; done
ディレクトリ内のすべてのファイルが必要ないため、ディレクトリ名全体をコピーすることはできません。
答え1
特定のファイルまたはディレクトリの完全なディレクトリパスを別のディレクトリにコピーするには、少なくとも2つのオプションがあります。
cp
GNU coreutils で以下を使用します--parents
。
cp --parents ./*/sourcefile /some/path/destdir
rsync
、使用-R
または--relative
:
rsync -R ./*/sourcefile /some/path/destdir
たとえば、ここに示されているコマンド./a/sourcefile
にコピーするために、ターゲットディレクトリのソースパスの下に各ソースファイルが配置されます。/some/path/destdir/a/sourcefile
これを行うときにファイルを繰り返す必要はありません。
cp
GNUを持たないシステムではrsync
ループを実行できますが、ループの出力は望ましくありませんls
。代わりに
for pathname in ./*/sourcefile; do
destdir="/some/path/destdir/$(dirname "$pathname")"
mkdir -p "$destdir" && cp "$pathname" "$destdir"
done
これはコピーするすべてのファイルを繰り返し、各ファイルに対応するターゲットディレクトリがあることを確認し、そこにファイルをコピーします。
例:
$ tree
.
|-- dest
`-- src
|-- a
| |-- file
| `-- something-else
|-- b
| |-- file
| `-- something-else
|-- c
| |-- file
| `-- something-else
|-- d
| |-- file
| `-- something-else
`-- e
|-- file
`-- something-else
7 directories, 10 files
ここに上記の2つのコマンド(またはループ)のいずれかを入力します。ソースは、./src/*/file
ターゲットはです./dest
。
$ tree
.
|-- dest
| `-- src
| |-- a
| | `-- file
| |-- b
| | `-- file
| |-- c
| | `-- file
| |-- d
| | `-- file
| `-- e
| `-- file
`-- src
|-- a
| |-- file
| `-- something-else
|-- b
| |-- file
| `-- something-else
|-- c
| |-- file
| `-- something-else
|-- d
| |-- file
| `-- something-else
`-- e
|-- file
`-- something-else
13 directories, 15 files
答え2
これを行うには、rsync -R(--relative)フラグを使用してみてください。
$ for i in ls ./*/filename; do rsync -avR $i ../test2; done
-Rフラグは、コマンドラインに提供されているフルパスを同期します。