捕获发现的输出。 -print0成一个bash数组 [英] Capturing output of find . -print0 into a bash array

查看:171
本文介绍了捕获发现的输出。 -print0成一个bash数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用找到。 -print0 似乎是获得在bash的文件列表的唯一安全的方法,由于含有空格,换行,引号等的文件名的可能性。

Using find . -print0 seems to be the only safe way of obtaining a list of files in bash due to the possibility of filenames containing spaces, newlines, quotation marks etc.

不过,我有一个很难做出真正的bash内或与其他命令行实用程序发现的输出非常有用。我已成功地利用输出的唯一方法是通过管道它Perl和改变Perl的IFS为空:

However, I'm having a hard time actually making find's output useful within bash or with other command line utilities. The only way I have managed to make use of the output is by piping it to perl, and changing perl's IFS to null:

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

这个例子打印找到的文件的数量,避免换行符的文件名中破坏计数危险,因为会发生与

This example prints the number of files found, avoiding the danger of newlines in filenames corrupting the count, as would occur with:

find . | wc -l

由于大多数的命令行程序不支持空分隔的投入,我想最好的办法是捕捉到的输出找到。 -print0 在bash阵列,就像我在perl的做了上面的代码,然后与任务,不管它可能会继续下去。

As most command line programs do not support null-delimited input, I figure the best thing would be to capture the output of find . -print0 in a bash array, like I have done in the perl snippet above, and then continue with the task, whatever it may be.

我怎样才能做到这一点?

How can I do this?

这不工作:

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

一个更普遍的问题可能是:我该怎么做有益的事情与文件列表在bash

A much more general question might be: How can I do useful things with lists of files in bash?

推荐答案

的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&LT;&LT;(CMD2))类似,但并不完全一样更常见的管道( CMD2 | CMD1 ) - 如果命令是shell内建命令(例如,而),管线版本执行它们在子shell,并他们设置任何变量(例如数组 A )都将丢失,当他们退出。 CMD1&LT; ≤(CMD2)只能运行在一个子shell CMD2,所以阵列住过去施工。警告:这种形式的重定向只在bash可用,甚至没有在bash的SH-仿真模式;您必须使用#开始你的脚本!/斌/庆典

Note that the redirection construct used here (cmd1 < <(cmd2)) is similar to, but not quite the same as the more usual pipeline (cmd2 | cmd1) -- if the commands are shell builtins (e.g. while), the pipeline version executes them in subshells, and any variables they set (e.g. the array a) are lost when they exit. cmd1 < <(cmd2) only runs cmd2 in a subshell, so the array lives past its construction. Warning: this form of redirection is only available in bash, not even bash in sh-emulation mode; you must start your script with #!/bin/bash.

此外,因为文件处理步骤(在这种情况下,只需 A [I +] =$文件,但你可能想直接在做一些票友环路)已其输入重定向,它不能使用,可能从stdin读取的任何命令。为避免这一问题,我倾向于使用:

Also, because the file processing step (in this case, just a[i++]="$file", but you might want to do something fancier directly in the loop) has its input redirected, it cannot use any commands that might read from stdin. To avoid this limitation, I tend to use:

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通过文件列表,而不是标准输入。

...which passes the file list via unit 3, rather than stdin.

这篇关于捕获发现的输出。 -print0成一个bash数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆