Ответ 1
Вероятно, вы просто хотите cp -R $1/* $2/
- рекурсивную копию.
(Если могут быть скрытые файлы (те, чьи имена начинаются с точки), вы должны префикс этой команды с помощью shopt -s dotglob;
, чтобы убедиться, что они совпадают.)
Я ищу оболочку script, которая объединяет файлы из одного каталога в другой.
Пример:
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
остался нетронутым
Вероятно, вы просто хотите cp -R $1/* $2/
- рекурсивную копию.
(Если могут быть скрытые файлы (те, чьи имена начинаются с точки), вы должны префикс этой команды с помощью shopt -s dotglob;
, чтобы убедиться, что они совпадают.)
cp -RT source/ destination/
Все файлы и каталоги в source
окажутся в destination
. Например, source/file1
будет скопирован в destination/file1
.
Флаг -T
останавливает копирование source/file1
в destination/source/file1
. (К сожалению, cp
в macOS не поддерживает флаг -T
.)
Посмотрите att rsync
rsync --recursive html/ html_new/
Rsync получил множество флагов для установки, так что смотрите man-страницу rsync для деталей
Просто используйте rsync - это отличный инструмент для локального копирования и объединения файлов в дополнение к удаленному копированию.
rsync -av /path/to/source_folder/ /path/to/destination_folder/
Обратите внимание, что косая черта в исходной папке необходима для копирования только содержимого source_folder в место назначения. Если вы не включите его, он скопирует исходную папку и ее содержимое, что, вероятно, не то, что вы ищете, поскольку вы хотите объединить папки.
Не работает cp -r
?
cp -r html_new/* html
или (поскольку первая версия не будет копировать файлы .something)
cd html_new; cp -r . ../html
Обратите внимание, что -r
читает из труб, если любой из файлов в скопированном каталоге - это трубы. Чтобы этого избежать, используйте -r
вместо этого.
cd html
cp -r . /path/to/html_new
Несмотря на то, что этот вопрос и его принятый ответ являются древними, я добавляю свой ответ, потому что существующие существующие с помощью cp
либо не обрабатывают некоторые краевые случаи, либо требуют интерактивной работы. Часто кросс-кейсы/возможность сценариев/переносимость/несколько источников не имеют значения, но в этом случае простота выигрывает, и лучше использовать cp
напрямую с меньшим количеством флагов (как и в других ответах) для уменьшения когнитивной нагрузки, но для в те другие времена (или для надежной функции повторного использования) эта функция вызова полезна и, кстати, не является bash -специфичной (я понимаю, что этот вопрос касался bash, хотя, так что просто бонус в этом случае). Некоторые флаги могут быть сокращены (например, с помощью -a
), но я включил все явно в длинную форму (за исключением -R
, см. Ниже) для объяснения. Очевидно, просто удалите любые флаги, если есть какая-то особенность, которую вы специально не хотите (или вы находитесь в ОС, отличной от posix, или ваша версия cp
не обрабатывает этот флаг - я тестировал это на GNU coreutils 8.25 cp
):
mergedirs() {
_retval=0
_dest="$1"
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
на некоторых системах (особенно в отношении специальных файлов в исходных каталогах), как объяснено в этом ответе--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.
)yes
]: даже с --force
, в этом конкретном рекурсивном режиме cp
все еще запрашивает перед скремблированием каждого файла, поэтому мы достигаем неинтерактивности, выводящий из него yes
li > /dev/null
]: это отключить беспорядочную строку вопросов по строкам cp: overwrite 'xx'?
1
, если произошла ошибкаBTW:
--reflink=auto
для создания так называемых "легких копий" (копирование на запись с теми же преимуществами скорости, что и жесткая привязка, и того же размера выгоды до и в обратной пропорции к тому, насколько файлы будут расходиться в будущем). Этот флаг принят в недавнем GNU cp
и делает больше, чем no-op с совместимыми файловыми системами на последних ядрах Linux. YMWV-a-lot в других системах.