Чтобы скопировать полный путь к определенному файлу или каталогу в другой каталог, у вас есть по крайней мере два варианта:
С 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
в показанной здесь команде.
Обратите внимание, что при этом нет необходимости перебирать какие-либо файлы.
В системе без GNU cp
и 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
Любая из двух вышеуказанных команд (или цикл ), введенный здесь, с источником ./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