array – 捕获find的输出 -print0 into a bash array

使用find。 -print0似乎是获取bash文件列表的唯一安全方式,因为文件名包含空格,换行符,引号等的可能性。

但是,我有一个很难的时间实际上使得find的输出在bash或其他命令行实用程序有用。我已经设法利用输出的唯一方法是将其管道到perl,并将perl的IFS更改为null:

find . -print0 | perl -e '$/="\0"; @files=<>; print $#files;'

此示例打印找到的文件数,避免换行符在文件名中损坏计数的危险,如下所示:

find . | wc -l

由于大多数命令行程序不支持空定界输入,我想最好的事情是捕获find的输出。 -print0在一个bash数组,就像我在上面的perl代码片段,然后继续任务,无论它可能是什么。

我如何做到这一点?

这不工作:

find . -print0 | ( IFS=$'\0' ; array=( $( cat ) ) ; echo ${#array[@]} )

一个更常见的问题可能是:我如何可以使用bash中的文件列表做有用的事情?

无耻地从 Greg’s 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内置命令管道版本在子shell中执行它们,并且它们设置的任何变量(例如,数组a)在它们退出时丢失。 cmd1< <(cmd2)仅在子shell中运行cmd2,因此该数组过期。警告:此重定向形式仅在bash中可用,在sh-emulation模式下甚至不可用;您必须使用#!/ bin / bash启动脚本。 此外,因为文件处理步骤(在这种情况下,只是一个[i] =“$文件”,但你可能想直接在循环中做某些fancier)的输入重定向,它不能使用任何可能读取的命令stdin。为了避免这种限制,我倾向于使用:

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。

相关文章

用的openwrt路由器,家里宽带申请了动态公网ip,为了方便把2...
#!/bin/bashcommand1&command2&wait从Shell脚本并行...
1.先查出MAMP下面集成的PHP版本cd/Applications/MAMP/bin/ph...
1、先输入locale-a,查看一下现在已安装的语言2、若不存在如...
BashPerlTclsyntaxdiff1.进制数表示Languagebinaryoctalhexa...
正常安装了k8s后,使用kubect工具后接的命令不能直接tab补全...