Как объединить один каталог в другой с помощью Bash?
Я ищу скрипт, чтобы объединить файлы из одного каталога в другой.
пример:
html/
a/
b.html
index.html
html_new/
a/
b2.html
b.html
использование:
./mergedirs.sh html html_new
результат:
html/
a/
b.html
b2.html
index.html
html/a/b.html
был заменен html_new/a/b.html
html/a/b2.html
был скопирован из html_new/a/b2.html
html/index.html
был сохранен нетронутым
7 ответов:
Вы наверное просто хотите
cp -R /* /
- Это рекурсивная копия.(Если там могут быть скрытые файлы (те, чьи имена начинаются с точки), вы должны префикс команды с
shopt -s dotglob;
чтобы убедиться, что они совпадают.)
cp -RT source/ destination/
все файлы и каталоги в
source
в концеdestination
. Например,source/file1
будет скопировано вdestination/file1
.The
-T
останавливается флагsource/file1
от копирования кdestination/source/file1
вместо.
взгляните на rsync
rsync --recursive html/ html_new/
Rsync получил много флагов, чтобы установить так что смотрите на rsync manpage для деталей
просто используйте rsync-это отличный инструмент для локального копирования файлов и слияния в дополнение к удаленному копированию.
rsync -av /path/to/source_folder/ /path/to/destination_folder/
обратите внимание, что конечная косая черта в исходной папке необходима для копирования только содержимого папки source_folder в пункт назначения. Если вы оставите его, он будет копировать source_folder и это содержание, которое, вероятно, не то, что вы ищете, так как вы хотите объединить их.
не
cp -r
работы?cp -r html_new/* html
или (так как первая версия не будет копировать ".что-то" - файлы)
cd html_new; cp -r . ../html
обратите внимание:
-r
читает из трубы если какие-либо файлы в скопированном каталоге являются трубами. Чтобы избежать этого, используйте .
несмотря на то, что этот вопрос и его принятый ответ являются древними, я добавляю свой ответ, потому что существующие в настоящее время используют
cp
либо не обрабатывайте некоторые крайние случаи, либо требуйте интерактивной работы. Часто edge-cases / scriptability / portability / multiple-sources не имеют значения, хотя в этом случае выигрывает простота, и лучше использоватьcp
непосредственно с меньшим количеством флагов (как и в других ответах), чтобы уменьшить когнитивную нагрузку - но для тех другое раз (или для робастно многоразовая функция) этот вызов/функция полезна, и, кстати, не является специфичным для bash (я понимаю, что этот вопрос был о bash, так что это просто бонус в этом случае). Некоторые флаги могут быть сокращены (например,-a
), но я включил все явно в форме (за исключением-R
, см. ниже) ради объяснения. Очевидно, просто удалите любые флаги, если есть какая-то функция, которую вы специально не хотите (или вы находитесь на не-posix ОС, или ваша версияcp
не обрабатывает этот флаг - я проверил это на GNU coreutils 8.25 хcp
):mergedirs() { _retval=0 _dest="" shift yes | \ for _src do cp -R --no-dereference --preserve=all --force --one-file-system \ --no-target-directory "${_src}/" "$_dest" || { _retval=1; break; } done 2>/dev/null return $_retval } mergedirs destination source-1 [source-2 source-3 ...]
объяснение:
-R
: имеет слегка различную семантику от-r
/--recursive
в некоторых системах (особенно в отношении специальных файлов в исходных dirs), как описано в ответ--no-dereference
: никогда не переходите по символическим ссылкам в SOURCE--preserve=all
: сохранение указанных атрибутов (по умолчанию: режим,право собственности,метки), если это возможно, дополнительные атрибуты: контекст, ссылки, xattr, все--force
: если существующий файл назначения не может быть открыт, удалите его и повторите попытку--one-file-system
: оставайтесь в этой файловой системе--no-target-directory
: обработайте DEST как нормальный файл (объясненный внутри в ответ, а именно:If you do a recursive copy and the source is a directory, then cp -T copies the content of the source into the destination, rather than copying the source itself.
)- [piped input from
yes
]: даже с--force
, в этом конкретном рекурсивном режимеcp
еще просит перед тем, как забивать каждый файл, мы достигаем неинтерактивности, выводя вывод изyes
это- [трубам вывод
/dev/null
]: это для того, чтобы заставить замолчать беспорядочную строку вопросов по строкамcp: overwrite 'xx'?
- [return-val & early exit]: это гарантирует, что цикл завершается, как только есть неудачная копия, и возвращает
1
если произошла ошибкакстати:
- фанки новый флаг, который я также использую на моей системе это
--reflink=auto
для выполнения так называемых" легких копий " (копирование на запись, с той же скоростью, что и жесткая компоновка, и тот же размер выгоды до и обратно пропорционально тому, насколько файлы расходятся в будущем). Этот флаг принят в недавнем GNUcp
, и делает больше, чем no-op с совместимыми файловыми системами на последних ядрах Linux. YMWV много других систем.