Поскольку в вашем списке нет других пробелов, вы можете использовать sed
для замены первого пробела в каждой строке точкой с запятой:
sed 's/ /;/' file
Для rsync
нет механизма отслеживания переименований, поскольку он не поддерживает состояние, кроме как во время работы. Если вы переименуете /test/10GBfile
в /test/10GBfile_newname
на исходном компьютере, то по умолчанию rsync
будет видеть только то, что 10GBfile
было удалено, а 10GBfile_newname
создано.
Параметр --fuzzy
(-y
)может помочь идентифицировать 10GBfile
как потенциальный источник данных для 10GBfile_newname
на целевом объекте, тем самым избегая сетевой копии за счет копии файла. Однако он может (в основном )рассматривать только совпадения файлов в том же каталоге , поэтому, хотя ваш пример будет соответствовать, переименование /test/10GBfile
в /test/otherdir/10GBfile_newname
не будет.
Обратите также внимание на то, что документация(man rsync
)советует, если вы хотите использовать --delete
, вместо этого следует использовать --delay-updates
или --delete-after
, чтобы потенциальные совпадения для --fuzzy
не удалялись до того, как их можно будет использовать.
Пример
# Prepare an uncompressible 100MB file
mkdir -p /tmp/test
dd bs=1M count=100 iflag=fullblock if=/dev/urandom >/tmp/test/file1
# Normal first-time copy
rsync -av --fuzzy --delete-after /tmp/test/ remote:/tmp/test
# Skip copy because unchanged
rsync -av --fuzzy --delete-after /tmp/test/ remote:/tmp/test
# Rename file (per your example)
mv /tmp/test/file1 /tmp/test/file2
# Fast copy because fuzzy match
rsync -av --fuzzy --delete-after /tmp/test/ remote:/tmp/test
Добавьте еще два флага -v
(, т. е. rsync -avvv …
), чтобы увидеть блок -по блоку -подробно о том, что происходит.
--fuzzy
уже был дан ответ, но есть еще один интересный прием, связанный с жесткими ссылками.
После первой передачи
$ rsync -avHP --delete-after ~/family/Photos remotebox:backups
Вы создаете жесткий связанный рабочий каталог:
$ cd ~/family
$ cp -rlp Photos Photos-work
Затем вы можете использовать
$ rsync -avHP --delete-after --no-inc-recursive ~/family/Photos ~/family/Photos-work remotebox:backups
Для передачи новой структуры на удалённый.
Почему и как это работает, объясняется здесь:
https://lincolnloop.com/blog/detecting-file-moves-renames-rsync/
Эта страница утверждает, что исправления для опции --detect-renamed
были доступны для rsync 3.0.9
. Там есть ссылки на патчи, ссылка на обсуждение багзиллы . Мой rsync 3.1.3
не имеет опции --detect-renamed
. Упомянутая дискуссия ведется с:
elatllat 2021-01-15 14:19:12 UTC
This feature request is so old it has lost relavence because btrfs/zfs/etc are more optimal backup solutions than rsync.
Некоторые там не согласны с "потерянной актуальностью" и я согласен с теми, кто не согласен больше.
Эта страница Reddit утверждает:
btrfs sync supports this, but you need to have btrfs at both ends.
что я думаю, что elatllat упомянул.
Ниже мой обходной путь на данный момент(git
здесь для меня слишком много, я думаю ).
Мои особенности :Я переименовываю не часто и хочу синхронизировать в цепочку (не только один -на -один ), а не бэкап. Поэтому я решил создать командные файлы оболочки, в которых я буду писать mv
команд, которые будут выполняться дополнительно сценарием, который я написал изначально для запуска rsync туда и обратно. Этот сценарий на данный момент приводит к попытке переименовать дополнительное время, я надеюсь, что опция rsync --detect-renamed
скоро будет запущена в производство.
do_sync(){
if [ -d $remote_path ]; then
cd $local_path && $remote_path/_rename_move.sh
cd $remote_path && $local_path/_rename_move.sh
# below two lines result in growing size of files and multiple runs of same mv commands but
# as of now I have not deviced a better solution for chained sync,
# for only two points instead just empty the files with e.g. "> filename"
cat $remote_path/_rename_move.sh >> $local_path/_rename_move.sh
cat $local_path/_rename_move.sh >> $remote_path/_rename_move.sh
rsync $options $local_path/ $remote_path
rsync $options $remote_path/ $local_path
rsync $options $local_path/ $remote_path
# below is to put old versions away
find "$local_path" -path "$local_path/prevs" -prune -o -name '*.bak' -exec mv "{}" "$local_path/prevs" \;
find "$remote_path" -path "$remote_path/prevs" -prune -o -name '*.bak' -exec mv "{}" "$remote_path/prevs" \;
else
echo $remote_path is not available
fi
}
# trailing / would prevent proper pruning in find commands
local_path=/path1
remote_path=/path2
do_sync
Ответы вhttps://serverfault.com/questions/489289/handling-renamed-files-or-directories-in-rsyncимеют, насколько я понимаю, некоторые недостатки.
Один с жесткими ссылками :Большинство систем не поддерживают жесткие ссылки для каталогов, и он не будет проверять, на какой стороне изменено имя (Подходит для резервного копирования, не подходит для синхронизации ).
stat filename
можно использовать для проверки того, на какой стороне переименован файл, но я не знаю, как объединить его с rsync.