Как к слиянию копии два каталога?

Если Вы знаете, что это поле начинается \n во всех записях можно использовать sed следующим образом:

sed "N;s/|\n/|/"

избавиться от новой строки. Отметьте, это с тех пор sed использование \n как разделители строки, сначала необходимо соединить следующую строку с обработанной той ( N команда), во время этого процесса sed вставляет символ новой строки между строками, к которым присоединяются.

Если эта проблема возникает случайным образом (не в каждом записи), необходимо будет обратиться к более сильному инструменту для парсинга содержания файла - в основном необходимо считать поля. Также awk или perl может добиться цели изящно (я думаю, что это могло быть выполнено в sed а также, но Вы, вероятно, не хотите, идут то направление).

121
13.08.2014, 02:13
7 ответов

Это задание для rsync. Нет никакой пользы делать это вручную с помощью цикла оболочки, если только вы не хотите переместить файл, а не скопировать его.

rsync -a /path/to/source/ /path/to/destination

В вашем случае:

rsync -a /images2/ /images/

(Обратите внимание на трейлинговый слэш на изображениях2, иначе он будет скопирован в /изображения/изображения2.)

Если изображения с одинаковым именем существуют в обоих каталогах, команда выше перезапишет /изображения/SOMEPATH/SOMEFILE с помощью /изображения2/SOMEPATH/SOMEFILE. Если необходимо заменить только старые файлы, добавьте опцию -u. Если вы хотите, чтобы версия всегда сохранялась в /images, добавьте опцию --ignore-existing.

Если вы хотите переместить файлы из /images2, с помощью rsync можно передать опцию --remove-source-files. Затем rsync копирует все файлы по очереди и удаляет каждый файл по окончании работы. Это намного медленнее, чем перемещение, если исходный и конечный каталоги находятся в одной файловой системе.

184
27.01.2020, 19:29

Лучшим выбором, как уже было сказано, конечно же, является rsync. Тем не менее, unison был бы отличным программным обеспечением для этой работы. Оба могут использоваться в нескольких операционных системах.

Rsync

rsync синхронизирует в одном направлении от источника к месту назначения. Поэтому следующий оператор

rsync -avh --progress Source Destination

синхронизирует все, от источника до места назначения . Объединенная папка находится в Destination .

-a означает «архивировать» и рекурсивно копирует все из источника в место назначения, сохраняя почти все.

-v дает больше вывода («подробный»).

-h для чтения человеком.

- прогресс , чтобы показать, сколько работы выполнено.

Если вы хотите только обновить целевую папку новыми файлами из исходной папки:

rsync -avhu --progress source destination

Unison

unison синхронизируется в обоих направлениях. Поэтому следующий оператор

unison Source Destination

синхронизирует оба каталога в обоих направлениях и, наконец, источник равен месту назначения. Это как дважды выполнить rsync от источника к месту назначения и наоборот.

Для более продвинутого использования просмотрите страницы руководства или следующие веб-сайты:

  1. https://www.cis.upenn.edu/~bcpierce/unison/
  2. https://rsync.samba.org/
44
27.01.2020, 19:29
for dir in images2/*; do mv "$dir"/* "images/$(basename "$dir")"; done

Переберите все содержимое images2 , используя расширенный глобус (чтобы избежать проблем с синтаксическим анализом ls ), затем mv содержимое этих элементов в соответствующая запись в изображениях . Использует базовое имя , чтобы удалить ведущие изображения2 из глобального пути.

5
27.01.2020, 19:29

@ inulinux12, вы можете использовать следующую строку для цикла из командной строки:

$ for dir in images2/*; do mv "$dir"/* "${dir/2/}"; done

Это переместит все файлы из images2 на изображений в соответствующих каталогах. Примечание: это предполагает, что нет файлов с одинаковыми именами.

Например:

Перед выполнением:

$ ls -R images*
images:
ad  adfoo  fe
images/ad:
jpg.1  jpg.2
images/adfoo:
jpg.7
images/fe:
jpg.5
images2:
ad  adfoo  fe
images2/ad:
jpg.3
images2/adfoo:
jpg.6
images2/fe:
jpg.4

После выполнения:

$ ls -R images*
images:
ad  adfoo  fe
images/ad:
jpg.1  jpg.2  jpg.3
images/adfoo:
jpg.6  jpg.7
images/fe:
jpg.4  jpg.5
1
27.01.2020, 19:29

Существуют более быстрые и эффективные -способы объединения двух каталогов с использованием параметра --linkдля cp, если каталоги находятся в одной и той же файловой системе , описанные в нескольких различных ответы в связанной статье здесь:(Название статьи не совсем соответствует вопросу пользователя, а ответы относятся к заглавной теме, объединяясь, больше, чем к фактическому вопросу пользователя.)

Объединение папок с mv?

Параметр --linkдля cpозначает, что данные файла не копируются. Примером этого, когда все в /images2заменяет любые старые элементы в /images, является:

cp --force --archive --update --link /images2/. /images

После слияния с /imagesвы можетеrm -rf /images2

Это решение потерпит неудачу, если где-либо в дереве файлов слияние попытается объединить каталог с существующим файлом или символической ссылкой с тем же именем, т. е. оно не объединит каталог с именем /images2/xс существующим файлом или символической ссылкой с то же имя /images/x, и если вы получите такую ​​​​ошибку, вы можете вручную удалить файл или символическую ссылку и просто повторно -запустить команду.

Прелесть --linkв том, что никакие данные не перемещаются для объединения каталогов.

4
29.12.2020, 11:32

Ответ на этот вопрос предельно прост. Я использовал его много раз.

Все, что вам нужно сделать, это...

cp -rf source_folder parent_of_dest_folder

Используя определенную файловую структуру в исходном вопросе, команда будет...

cp -rf /images/* /images2/

Результатом будет объединенная версия источника и места назначения. Это также будет рекурсивно обрабатывать подкаталоги.

1
27.09.2021, 18:31

Это эффективно объединяется с помощью команды cpбез перезаписи:

cp -prnv /images/* /images2/

Опции:

-p -- preserve ownership, perms and detailed attributes
-r -- recursive
-n -- no overwrite
-v -- verbose (display operation detail for each file)

Чтобы увидеть, что на самом деле было скопировано, запустите его таким образом:

cp -prnv /images/* /images2/ | grep '\->'  # shows copies

Чтобы увидеть противоположное тому, что не скопировано, используйте grep -v '\->'.

Если вы хотите сделать что-то более сложное, например, заменить файлы различиями, используйте rsyncили запустите свой собственный, протестировав md5sumс обеих сторон, затем копирование на основе кода выхода diff(не рекомендуется для больших файлов или больших каталогов --используйтеrsync).

0
02.11.2021, 00:17

Теги

Похожие вопросы