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

前端之家收集整理的这篇文章主要介绍了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。

原文链接:https://www.f2er.com/bash/392381.html

猜你在找的Bash相关文章