rsync 模式匹配名称

rsync 模式匹配名称

我想 rsync 一堆文件,并在匹配要同步的内容时忽略名称中的任何大小写、空格、句点、破折号或下划线差异。

因此,作为一个极端的例子,“TheFilename.zip”将匹配“__THE- - -File---nam-e...._.zip”(假设大小和时间匹配)。

我想不出办法来做到这一点。

答案1

这个脚本可能会做你想要的

#!/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当您对它按预期工作感到满意时将其删除。

答案2

正如 Satō Katsura 在评论中指出的那样,这是不可能rsync开箱即用的。这也是我认为rsync不应该做的事情。

如果您正在复制单个文件,如果该文件名在变量中可用name__THE- - -File---nam-e...._.zip那么您可以从文件名中删除不需要的字符并复制文件,如下所示:

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

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

因为name='__THE- - -File---nam-e...._.zip'$ext将会zip并且$shortname将会__THE- - -File---nam-e...._

如果您的 shell 不支持${parameter//word},请使用

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

两者都${shortname//[-_ .]}.$ext$(printf '%s' "$shortname" | tr -d '-_ .' ).$ext成为THEFilename.zip

相关内容