Подтвердить что ты не робот

Как слить один каталог в другой с помощью Bash?

Я ищу оболочку 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 остался нетронутым

4b9b3361

Ответ 1

Вероятно, вы просто хотите cp -R $1/* $2/ - рекурсивную копию.

(Если могут быть скрытые файлы (те, чьи имена начинаются с точки), вы должны префикс этой команды с помощью shopt -s dotglob;, чтобы убедиться, что они совпадают.)

Ответ 2

cp -RT source/ destination/

Все файлы и каталоги в source окажутся в destination. Например, source/file1 будет скопирован в destination/file1.

Флаг -T останавливает копирование source/file1 в destination/source/file1. (К сожалению, cp в macOS не поддерживает флаг -T.)

Ответ 3

Посмотрите att rsync

rsync --recursive html/ html_new/

Rsync получил множество флагов для установки, так что смотрите man-страницу rsync для деталей

Ответ 4

Просто используйте rsync - это отличный инструмент для локального копирования и объединения файлов в дополнение к удаленному копированию.

rsync -av /path/to/source_folder/ /path/to/destination_folder/

Обратите внимание, что косая черта в исходной папке необходима для копирования только содержимого source_folder в место назначения. Если вы не включите его, он скопирует исходную папку и ее содержимое, что, вероятно, не то, что вы ищете, поскольку вы хотите объединить папки.

Ответ 5

Не работает cp -r?

cp -r html_new/* html

или (поскольку первая версия не будет копировать файлы .something)

cd html_new; cp -r . ../html

Обратите внимание, что -r читает из труб, если любой из файлов в скопированном каталоге - это трубы. Чтобы этого избежать, используйте -r вместо этого.

Ответ 6

cd html
cp -r . /path/to/html_new

Ответ 7

Несмотря на то, что этот вопрос и его принятый ответ являются древними, я добавляю свой ответ, потому что существующие существующие с помощью 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'?
  • [return-val и ранний выход]: это гарантирует, что цикл завершается, как только происходит сбой, и возвращает 1, если произошла ошибка

BTW:

  • Фламандский новый флаг, который я также использую с этим в моей системе, - это --reflink=auto для создания так называемых "легких копий" (копирование на запись с теми же преимуществами скорости, что и жесткая привязка, и того же размера выгоды до и в обратной пропорции к тому, насколько файлы будут расходиться в будущем). Этот флаг принят в недавнем GNU cp и делает больше, чем no-op с совместимыми файловыми системами на последних ядрах Linux. YMWV-a-lot в других системах.