rsync获取仅文件名列表

时间:2012-02-01 19:53:09

标签: file list filenames rsync

以下是我使用的命令示例:

rsync --list-only --include "*2012*.xml" -exclude "*.xml" serveripaddress::pt/dir/files/ --port=111 > output.txt

如何在没有权限,时间戳等额外信息的情况下获取文件名列表?

编辑:是否可以在新行上输出每个文件名?

4 个答案:

答案 0 :(得分:7)

经过多年的努力,这是我解决这个古老问题的方法:

DIR=`mktemp -d /tmp/rsync.XXXXXX`
rsync -nr --out-format='%n' serveripaddress::pt/dir/files/ $DIR > output.txt
rmdir $DIR

答案 1 :(得分:2)

希望将问题转移到相应的网站,不过我会在这里回答。

您可以附加awk的管道:

rsync ... | awk '{ $1=$2=$3=$4=""; print substr($0,5); }' >output.txt

这可以通过输出第5个字段中的所有内容来消除所有不需要的信息,但只有在输出格式的前四个字段中没有一个在某处获得额外的空格时才会起作用(这是不太可能的)。

如果文件名以空格开头,则此awk解决方案将无效。

更强大的解决方法可能是一个相当复杂的程序,也可以做出假设。

它以这种方式工作:对于每一行,

  • 切断前10个字节。验证它们后面跟着许多空格。切断它们。
  • 切断所有后续数字。确认它们后跟一个空格。切断它。
  • 切断接下来的19个字节。验证它们是否包含适当格式的日期和时间戳。 (我不知道为什么日期的组件与/而不是-分开 - 它不符合ISO 8601。)
  • 确认现在有一个空格。切断它。保留以下任何空格字符,因为它们属于文件名。
  • 如果测试已通过所有这些验证,则该行的其余部分可能包含文件名。

情况变得更糟:对于非常深奥的角落情况,还有更多值得关注的事情:文件名可以被转义。某些不可打印的字节被转义序列替换(#oooooo是它们的八进制代码),这个过程必须颠倒过来。

因此,如果我们想要正确地执行此操作,awk和简单sed脚本都不会在此处执行。

相反,可以使用以下Python脚本:

def rsync_list(fileobj):
    import re
    # Regex to identify a line
    line_re = re.compile(r'.{10} +\d+ ..../../.. ..:..:.. (.*)\n')
    # Regex for escaping
    quoted_re = re.compile(r'\\#(\d\d\d)')
    for line in fileobj:
        match = line_re.match(line)
        assert match, repr(line) # error if not found...
        quoted_fname = match.group(1) # the filename part ...
        # ... must be unquoted:
        fname = quoted_re.sub( # Substitute the matching part...
            lambda m: chr(int(m.group(1), 8)), # ... with the result of this function ...
            quoted_fname)                      # ... while looking at this string.
        yield fname

if __name__ == '__main__':
    import sys
    for fname in rsync_list(sys.stdin):
        #import os
        #print repr(fname), os.access(fname, os.F_OK)
        #print repr(fname)
        sys.stdout.write(fname + '\0')

这将输出由NUL字符分隔的文件名列表,类似于find -print0和许多其他工具的工作方式,以便即使包含换行符(有效!)的文件名也能正确保留:< / p>

rsync . | python rsf.py | xan -0 stat -c '%i'

正确显示每个给定文件的inode编号。

当然我可能错过了我没想到的那个或其他角落的情况,但我认为脚本正确处理了大多数情况(我测试了所有255个可想到的单字节文件名以及文件名称以空格开头。)

答案 2 :(得分:0)

rsync ... | sed -E 's|^([^\s]+\s+){4}||'

答案 3 :(得分:0)

进一步到https://stackoverflow.com/a/29522388/2858703

如果您的mktemp支持--dry-run选项,则无需实际创建临时目录:

rsync -nr --out-format='%n' serveripaddress::pt/dir/files/ $(mktemp -d --dry-run) > output.txt