Использование терминала Mac OS X для копирования выбранных папок в новое место с возможностью объединения

Использование терминала Mac OS X для копирования выбранных папок в новое место с возможностью объединения

У меня есть папка «foo», которая содержит много подпапок, например

foo
 |---20101
 |---20102
 |---20103
 |---20111
 |---20112
 |---20113

Их гораздо больше, но, надеюсь, это объясняет сценарий. Теперь я хочу скопировать все папки из этой папки, которые начинаются на '2011', в родственную папку 'foo' под названием 'bar'. Однако 'bar' уже содержит несколько папок с таким же именем

bar
 |---20111
 |---20113
 |---20114

Содержимое исходной и целевой папок должно быть объединено. Обратите внимание, что скрипту также потребуется создать папку bar/20112, поскольку она не существует.

Я новичок в написании скриптов для Mac Terminal и мне удалось успешно выполнить grep для нужных папок.

foo>ls | grep ^2011 

В нем перечислены нужные папки, но я понятия не имею, как передать это в соответствующую операцию копирования.

решение1

Команда копирования — cp. Если вы дадите ей -rфлаг (рекурсивный), она сделает именно то, что вам нужно: скопирует файлы в существующие папки и создаст новые папки, если папка назначения отсутствует.

Однако,вы никогда не должны анализировать выводls, вам следует использовать findили, еще проще,подстановка bash:

cp -rv foo/2011* bar/

Если есть файлы и папки, имена которых начинаются с 2011, используйте findи его -execопцию, которая применит любую заданную вами команду ко всему найденному find(называется {}):

find foo/ -type d -name "2011*" -exec cp -rv '{}' bar/ \;

В этом конкретном случае нет смысла сохранять вывод команды и передавать его в cp. Иногда это необходимо, поэтому вот как это делается. В общем, вывод команды может быть передан в качестве ввода для другой команды, если поместить его в кавычки или $().

cp -rv `find foo/ -type d -name "2011*"` bar/

или

cp -rv $(find foo/ -type d -name "2011*") bar/

В качестве альтернативы вы можете выполнить циклический просмотр результатов:

for dir in $(find foo/ -type d -name "2011*"); do cp -rv "$dir" bar/; done

Это усложняется, если имена ваших файлов/папок могут содержать специальные символы или новые строки и т. п. В этом случае вам следует сделать что-то вроде этого:

find foo/ -type d -name "2011*" | while IFS= read -r dir; do 
       cp -rv "$dir" bar/; 
done

Связанный контент