Bash: рекурсивное копирование именованных файлов с сохранением структуры папок - PullRequest
93 голосов
/ 30 октября 2009

Я надеялся:

cp -R src/prog.js images/icon.jpg /tmp/package

приведет к симметричной структуре в директории назначения:

/tmp
|
+-- package
    |
    +-- src
    |   |
    |   +-- prog.js
    |
    +-- images
        |
        +-- icon.jpg

но вместо этого оба файла копируются в / tmp / package. Плоская копия. (Это на OSX).

Существует ли простая функция bash, которую я могу использовать для копирования всех файлов, включая файлы, указанные с помощью подстановочного знака (например, src / *. Js), в их законное место в каталоге назначения. Немного похоже на «для каждого файла, запустите mkdir -p $(dirname "$file"); cp "$file" $(dirname "$file")», но, возможно, одну команду.

Это актуальная тема, которая предполагает, что это невозможно. Однако авторское решение мне не очень полезно, потому что я хотел бы просто предоставить список файлов, подстановочных знаков или нет, и скопировать их всех в каталог назначения. IIRC MS-DOS xcopy делает это, но, похоже, нет эквивалента для cp.

Ответы [ 6 ]

140 голосов
/ 30 октября 2009

Вы пытались использовать опцию --parents? Я не знаю, поддерживает ли OS X это, но это работает на Linux.

cp --parents src/prog.js images/icon.jpg /tmp/package

Если это не работает в OS X, попробуйте

rsync -R src/prog.js images/icon.jpg /tmp/package

как и предполагалось.

21 голосов
/ 30 октября 2009

В одну сторону:

tar cf - <files> | (cd /dest; tar xf -)
17 голосов
/ 30 октября 2009

В качестве альтернативы, если вы старой школы, используйте cpio:

cd /source;
find . -print | cpio -pvdmB /target

Ясно, что вы можете отфильтровать список файлов по душе.

Параметр '-p' предназначен для режима 'сквозного' (в отличие от '-i' для ввода или '-o' для вывода). '-V' является многословным (перечислить файлы по мере их обработки). '-M' сохраняет время модификации. «-B» означает использовать «большие блоки» (где большие блоки 5120 байт вместо 512 байт); возможно, в наши дни это никак не отразится.

15 голосов
/ 30 октября 2009
Параметр

rsync -R сделает то, что вы ожидаете. Это очень многофункциональный копировщик файлов. Например:

$ rsync -Rv src/prog.js images/icon.jpg /tmp/package/
images/
images/icon.jpg
src/
src/prog.js

sent 197 bytes  received 76 bytes  546.00 bytes/sec
total size is 0  speedup is 0.00

Пример результатов:

$ find /tmp/package
/tmp/package
/tmp/package/images
/tmp/package/images/icon.jpg
/tmp/package/src
/tmp/package/src/prog.js
2 голосов
/ 30 октября 2009
1 голос
/ 30 октября 2009

Try ...

for f in src/*.js; do cp $f /tmp/package/$f; done

так что за то, что вы делали изначально ...

for f in `echo "src/prog.js images/icon.jpg"`; do cp $f /tmp/package/$f; done

или

v="src/prog.js images/icon.jpg"; for f in $v; do cp $f /tmp/package/$f; done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...