Помогите с командой script/rsync для перемещения файла со сравнением суммы md5 перед удалением исходного файла/ [закрыто]

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

awk '{ printf "%s", $NF; if (NR % 3 == 0) print ""; else printf "," }' second_file

Теперь вторая часть добавляет в файл1, что может быть выполнено простым перенаправлением >>

Полная команда тогда будет

 awk '{ printf "%s", $NF; if (NR % 3 == 0) print ""; else printf "," }' second_file >> first_file
1
11.07.2018, 00:08
1 ответ

Реализовать что-то подобное может быть сложно с первого раза, если вы заботитесь о файлах и не хотите напортачить. Итак, вот несколько альтернатив написанию полного скрипта на bash. Это более или менее сложные командные строки (oneliners ), которые могут помочь в вашей ситуации.

В вашем вопросе есть одна неопределенность :вы хотите сравнить каждый файл в исходном коде с каждым файлом в приемнике или только файлы с «совпадающими» именами файлов? (Это будет сравнение /path/to/src/aс /path/to/dest/aи /path/to/src/bс /path/to/dest/b, но не /path/to/src/aс /path/to/dest/bи так далее)

Я предполагаю, что вы хотите сравнивать только файлы с совпадающими путями!!

первая идея:diff

Старый добрыйdiffможет рекурсивно сравнивать каталоги. Также используйте параметр -q, чтобы просто увидеть, какие файлы отличаются, а не , чем они отличаются.

diff -r -q /path/to/source /path/to/dest

минусы

  • Это может занять длительное время в зависимости от размера жесткого диска.
  • При этом старые файлы не удаляются.
  • Результат не поддается разбору

плюсы

  • Это не удаляет файлы:)

Таким образом, после того, как вы вручную/визуально подтвердили, что нет никаких различий в каких-либо файлах, которые вам нужны, вы должны вручную удалить источник с помощью rm -rf /path/to/source.

вторая идея:rsync(редактировать :это может быть лучшим сейчас)

rsyncна мой взгляд является мастером среди всех инструментов командной строки для копирования (; ). Как упоминалось в комментариях к вашему вопросу, у него есть опция --checksum, но также есть множество других опций. Он может передавать файлы с локального на удаленный, с удаленного на локальный и с локального на локальный.Одна из наиболее важных особенностей, на мой взгляд, заключается в том, что если вы укажете правильные параметры, вы можете прервать и перезапустить команду (, снова выполнить ту же командную строку ), и она продолжится с того места, где она закончилась!

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

  • -v:подробный, показать, что происходит, можно указать несколько раз, но обычно достаточно одного
  • -n:пробный прогон, очень важно проверить материал, но ничего не делать (в сочетании с-v)!!
  • -c:использовать контрольную сумму, чтобы решить, что следует копировать
  • --remove-source-files:удаляет файлы, которые были успешно перенесены (на которые указал @brawny84, я не знал об этом и не нашел их на справочной странице при первом чтении)

Таким образом, эта команда перезапишет все файлы в dest, которые имеют другую контрольную сумму, чем соответствующий файл в source(, соответствующий имени ).

 rsync -a -c -v --remove-source-files -n /path/to/source /path/to/dest
 rsync -a -c -v --remove-source-files    /path/to/source /path/to/dest

плюсы

  • работает с контрольными суммами
  • имеет пробный режим
  • фактически скопирует все отсутствующие файлы и файлы, которые отличаются от источника к месту назначения
  • можно прервать и перезапустить
  • есть опция исключения, чтобы игнорировать некоторые файлы в src, если вы не хотите копировать все файлы
  • может удалять переданные исходные файлы

минусы

  • ??

третья идея:fdupes

Программаfdupesразработана мной для составления списка дубликатов файлов. Он проверяет md5sums по умолчанию.

плюсы

  • он использует md5 для сравнения файлов
  • у него есть опция --deleteдля удаления одного из дубликатов

минусы

  • он сравнивает каждый файл с каждым другим файлом , поэтому, если внутри самого приемника есть дубликаты файлов, он также перечислит их
  • режим удаления кажется интерактивным,вы должны подтвердить для каждого набора одинаковых файлов, что может быть невозможно для больших деревьев каталогов
  • неинтерактивный режим удалит все файлы, кроме первого, из каждого набора одинаковых файлов. Но я понятия не имею, какой первый файл (в источнике или в месте назначения?)

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

Я бы начал с чего-то подобного, если это нужно делать вручную. Я не проверял это, попробуйте сначала с lsи попытайтесь выяснить, будет ли это что-то тормозить!!

#!/bin/bash
# first require that the source and dest dirs
# are given as arguments to the script.
src=${1:?Please give the source dir as first argument}
dest=${2:?Please give the destination dir as second argument}
# go to the source directory
cd "$src"
# This assumes that there are no newlines in filenames!
# first find all plain files in the current dir 
# (which should be $src)
# then use xargs to hand the filenames to md5sum 
# pipe the md5 sums into a subshell
# go to the dest in the subshell
# read the md5sums from stdin and use md5sum -c to check them 
# After the subshell filter lines to only keep those that end in "OK"
# and at the same time remove the "OK" stuff after the file name
# use xargs to hand these file names to ls or rm.
find. -type f | \
  xargs md5sum | \
  ( cd "$dest" && md5sum -c ) | \
  sed -n 's/: OK$//p' | \
  xargs ls

lsв последней строке — список всех файлов, прошедших проверку. Если вы замените его на rm, они будут удалены из исходного каталога (текущего каталога послеcd "$src").

1
27.01.2020, 23:43

Теги

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