Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
File rsync以获取仅包含文件名的列表_File_List_Filenames_Rsync - Fatal编程技术网

File rsync以获取仅包含文件名的列表

File rsync以获取仅包含文件名的列表,file,list,filenames,rsync,File,List,Filenames,Rsync,下面是我正在使用的命令的一个示例: rsync --list-only --include "*2012*.xml" -exclude "*.xml" serveripaddress::pt/dir/files/ --port=111 > output.txt 我怎样才能在没有权限、时间戳等额外信息的情况下只获得文件名的列表 编辑:是否可以将每个文件名输出到新的一行?希望问题能够转移到适当的站点,我将在这里回答 可以使用awk附加管道: rsync ... | awk '{ $1=$2=

下面是我正在使用的命令的一个示例:

rsync --list-only --include "*2012*.xml" -exclude "*.xml" serveripaddress::pt/dir/files/ --port=111 > output.txt
我怎样才能在没有权限、时间戳等额外信息的情况下只获得文件名的列表


编辑:是否可以将每个文件名输出到新的一行?

希望问题能够转移到适当的站点,我将在这里回答

可以使用
awk
附加管道:

rsync ... | awk '{ $1=$2=$3=$4=""; print substr($0,5); }' >output.txt
这通过输出第5个字段中的所有内容来消除所有不需要的信息,但只有在输出格式的前四个字段中没有一个在某处获得额外的空白(这是不可能的)时才起作用

如果文件名以空格开头,此
awk
解决方案将不起作用

一个更可靠的解决方法可能是一个相当复杂的程序,它也会做出假设

它是这样工作的:对于每一行

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

更糟糕的是:对于非常深奥的角落案例,还有更多的事情需要注意:文件名可以转义。某些无法打印的字节被转义序列替换(
#ooo
,其中
ooo
是它们的八进制码),这一过程必须颠倒

因此,如果我们想正确地执行,那么无论是
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
和许多其他工具的工作方式,以便即使包含换行符(有效!)的文件名也能正确保留:

rsync . | python rsf.py | xan -0 stat -c '%i'
正确显示每个给定文件的索引节点号


当然,我可能错过了我没有想到的一个或另一个极端情况,但我认为脚本正确地处理了大多数情况(我测试了所有255个可思考的单字节文件名以及以空格开头的文件名)。

rsync…|sed-E的|^([^\s]+\s+{4}| |’

经过多年的工作,下面是我对这个古老问题的解决方案:

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

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

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

awk可能更适合这种情况,因为awk理解最后一个字段操作符
rsync…|awk“{print$NF}”
像这样晦涩而脆弱的解决方案绝对不能使用。@rbtux祝你好运,有一个文件名,比如
我最喜欢的歌曲.mp3
@Ark kun你说得对;我原来的解决方案与一个大小超过9999999999的文件断开。@glglgl当rsync输出所有者名称时,
cut-c 44-
解决方案如何工作?这是一个很好的例子,说明了流行的*nix shell(以及PowerShell修复的)的问题。其他可能的问题措辞:如何使用
rsync
包含和排除语法过滤
find
?同样,这可能会起作用,但我不确定是否有记录:
rsync-nr--out format='%n'serveripaddress::pt/dir/files//dev/false>output.txt
和否,
/dev/null
无效谢谢@bxm的注释
rsync-nr--out格式='%n'服务器IP地址::pt/dir/files/$(mktemp-d--dry run)>output.txt