【问题标题】:How to use NULL (\0) as the delimiter in GNU sort如何在 GNU 排序中使用 NULL (\0) 作为分隔符
【发布时间】:2011-09-27 16:25:01
【问题描述】:

我正在寻找一种方法来对 find 的结果进行排序,正确返回多个目录,以便在 bash 脚本中进行进一步处理。因为文件名不能包含 NULL (\0) 字符,所以我认为这将为通过管道传输到 sort 的结果提供很好的分隔符。

所以这就是我所期望的那样工作:

find ./ -maxdepth 1 -type d -iname 'xyz?' -print0 | sort -t $'\0'

但遗憾的是我得到了compaint sort: empty tab

四处寻找解释 a 发现了一个 question leading to a similar result,该操作描述为工作正常(请参阅 4 月 26 日的卢卡斯评论)。就我而言(使用 GNU sort v 7.4),这似乎有所不同。

我还通过管道检查了 find 的输出到 od -c 但这仅表明结果文件夹按预期由 NULL 分隔。

这里有没有人遇到过类似的情况,并且可能找到了解决方案或解释为什么 \0 似乎是不可能的排序分隔符?

期待你的答案...

编辑:请注意,此处使用 find-command 作为示例,更简单的测试/说明方法可能是 echo "g\0u\0b\0k" | sort -t $'\0'

【问题讨论】:

  • 您的 sort 版本不支持 -z 选项吗?我使用的是 5.93 版本,它支持 -z 用于以空结尾的条目。
  • 哦,是的!我真的应该了解行和字段分隔符之间的区别!非常感谢!

标签: bash sorting


【解决方案1】:

-t字段 分隔符。如果您想使用\0 作为 分隔符,那么您需要使用-z

【讨论】:

    【解决方案2】:

    如需进一步处理 Bash 脚本,请参阅:

    Capturing output of find . -print0 into a bash array

    # cf. http://mywiki.wooledge.org/BashFAQ/020
    unset a i
    while IFS='' read -r -d $'\0' dir; do
       a[i++]="$dir"        # or however you want to process each directory
    done < <(find ./ -maxdepth 1 -type d -iname 'xyz?' -print0 | LC_ALL=C sort -z)
    
    printf '%s\n' "${#a[@]}"
    printf '%s\n' "${a[@]}"
    
    # btw, you may use printf to add zero bytes
    printf '%c\000' g u b k | sort -z | tr '\0' ' '
    printf '%s\000' g1 u2 b3 k4 | sort -z | tr '\0' ' '
    

    【讨论】:

    • 如果检查了@jeff 的 bashFAQ 链接(非常有趣!)并发现在 while 循环中对 IFS='' 的解释对于不意外修剪空白是必要的。所以IFS=IFS=''IFS=$'\0'在这里代表同样的事情:NUL
    【解决方案3】:

    sort 零终止数据集使用-z 选项:

    find ./ -maxdepth 1 -type d -iname 'xyz?' -print0 | sort -z | tr '\0' '\n'
    

    【讨论】:

    • 在末尾将 NULL 转换为换行符是一个有趣的想法,但在我看来,包括换行符在内的文件名会引起同样的问题,就好像换行符从一开始就被选为分隔符一样......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多