У меня есть папка «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