使用find . -print0似乎是获得在bash的文件列表的唯一可靠的方式因含有空格,换行,引号等文件名的可能性
但是,我很难在bash或其他命令行实用程序中使find的输出有用。我设法利用输出的唯一方法是将其通过管道传递给perl,并将perl的IFS更改为null:
find . -print0 | perl -e '$/="\0"; @files=<>; print $#files;' 本示例将打印找到的文件数,避免文件名中的换行符损坏计数的危险,如发生以下情况:
find . | wc -l 由于大多数命令行程序不支持以空分隔的输入,因此我认为最好的办法是find . -print0像在上述perl片段中所做的那样,捕获bash数组中的输出,然后继续执行该任务,无论如何是。
我怎样才能做到这一点?
这不起作用:
find . -print0 | ( IFS=$'\0' ; array=( $( cat ) ) ; echo ${#array[@]} ) 一个更普遍的问题可能是:如何使用bash中的文件列表来做有用的事情?
问题来源于stack overflow
从无耻地窃取Greg的BashFAQ:
unset a i while IFS= read -r -d $'\0' file; do a[i++]="$file" # or however you want to process each file done < <(find /tmp -type f -print0) 请注意,此处使用的重定向构造(cmd1 < <(cmd2))与更常用的管道(cmd2 | cmd1)类似,但并不完全相同-如果命令是shell内置命令(例如while),则管道版本将在子shell中执行它们,并设置它们的任何变量(例如array a)退出时会丢失。 cmd1 < <(cmd2)仅在子外壳中运行cmd2,因此该阵列的寿命超过了其构造。警告:这种形式的重定向仅在bash中可用,甚至在sh-emulation模式下也不可用;您必须以开头脚本#!/bin/bash。
另外,由于文件处理步骤(在本例中为,a[i++]="$file"但您可能想直接在循环中做一些更有趣的事情)的输入已重定向,因此它不能使用任何可能从标准输入中读取的命令。为了避免这种限制,我倾向于使用:
unset a i while IFS= read -r -u3 -d $'\0' file; do a[i++]="$file" # or however you want to process each file done 3< <(find /tmp -type f -print0) ...通过单元3而不是stdin传递文件列表。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。