Имена сопоставления с образцом rsync

GNU sort имеет -V, который в основном может справиться с подобным списком (подробности):

 -V, --version-sort
        natural sort of (version) numbers within text

$ cat vers
release-5.0.19
release-5.0.19~pre1
release-5.0.19-bigbugfix
release-5.0.2
release-5.0.20
$ sort -V vers
release-5.0.2
release-5.0.19~pre1
release-5.0.19
release-5.0.19-bigbugfix
release-5.0.20

Однако, эти .rc* версии могут быть некоторой проблемой, поскольку они, вероятно, должны быть отсортированы перед соответствующей неrc версией, если таковые имеются. Некоторые системы версионирования (например, Debian) используют суффиксы, начинающиеся с тильды (~), чтобы отметить предварительные версии, и они сортируются перед версией без суффикса, которая сортируется перед версиями с другими суффиксами. Очевидно, это поддерживается по крайней мере sort в моей системе, как показано выше (sort (GNU coreutils) 8.23).

1
07.07.2017, 02:01
2 ответа

Этот сценарий, вероятно, сделает то, что вы хотите

#!/bin/bash
#
ritem="$1"              # [ user@ ] remotehost : [ / ] remotepath_to_directory
shift

rhost="${ritem/:*}"     # Can be remotehost or user@remotehost
rpath="${ritem/*:}"     # Can be absolute or relative path to a directory

# Get list of files on remote
#
echo "Looking in $rpath on $rhost" >&2
ssh -n "$rhost" find "$rpath" -maxdepth 1 -type f -print0 |
    while IFS= read -r -d $'\0' rfile
    do
        rkey=$(printf "%s" "$rfile" | tr -d '[:space:]_. -' | tr '[:upper:]' '[:lower:]')
        list[${rkey/*\/}]="$rfile"
    done


# Get list of files from local and copy to remote
#
ss=0

echo "Considering $*" >&2
for lpath in "$@"
do
    test -f "$lpath" || continue

    lfile="${lpath/*\/}"
    lkey=$(printf "%s" "$lfile" | tr -d '[:space:]_. -' | tr '[:upper:]' '[:lower:]')

    # Do we have a match in the map
    rfile="${list[$lkey]}"
    test -z "$rfile" && rfile="$lfile"

    # Copy across to the remote system
    echo "Copying $lpath to $rhost:$rpath/$rfile" >&2
    rsync --dry-run -av "$lpath" "$rhost":"$rpath/$rfile" || ss=$((ss+1))
done


# All done. Exit with the number of failed copies
#
exit $ss

Пример использования

375871.sh remotehost:remotepath localpath/*

Удалить --dry-run, когда вы счастлив, что это работает, как ожидалось.

1
27.01.2020, 23:45

Как отмечает Сато Катсура в комментариях, это невозможно сделать с помощью rsyncиз коробки. Я также думаю, что rsyncэтого делать не следует.

Если вы копируете один файли если это имя файла доступно в переменной имякак __THE- - -File---name-e.. .._.zip, то вы можете удалить ненужные символы из имени файла и скопировать файл следующим образом:

ext=${name##*.}
shortname=${name%.$ext}

rsync -a "$name" "user@target:${shortname//[-_ .]}.$ext"

Для name='__THE- - -File---name-e... ._.zip', $extбудет zip, а $shortnameбудет __THE- - -File---nam- е...._.

Если ваша оболочка не поддерживает ${parameter//word}, используйте

rsync -a "$name" "user@target:$(printf '%s' "$shortname" | tr -d '-_ .' ).$ext"

Both ${shortname//[-_ .]}.$extи $(printf '%s' "$shortname" | tr -d '-_ .' ).$extстанет THEFilename.zip.

0
27.01.2020, 23:45

Теги

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