Bash 脚本 - 迭代 find 的输出

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21663090/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 09:31:29  来源:igfitidea点击:

Bash Script - iterating over output of find

linuxbashshellscripting

提问by Nate Mara

I have a bash script in which I need to iterate over each line of the ouput of the find command, but it appears that I am iterating over each Word (space delimited) from the find command. My script looks like this so far:

我有一个 bash 脚本,我需要在其中遍历 find 命令输出的每一行,但似乎我正在遍历 find 命令中的每个 Word(空格分隔)。到目前为止,我的脚本如下所示:

folders=`find -maxdepth 1 -type d`

for $i in $folders
do
    echo $i
done

I would expect this to give output like:

我希望这会给出如下输出:

./dir1 and foo
./dir2 and bar
./dir3 and baz

But I am insted getting output like this:

但是我得到了这样的输出:

./dir1
and
foo
./dir2
and
bar
./dir3
and
baz

What am I doing wrong here?

我在这里做错了什么?

回答by Charles Duffy

folders=`foo`

is always wrong, because it assumes that your directories won't contain spaces, newlines (yes, they're valid!), glob characters, etc. One robust approach (which requires the GNU extension -print0) follows:

总是错误的,因为它假设您的目录不包含空格、换行符(是的,它们是有效的!)、glob 字符等。一种强大的方法(需要 GNU 扩展-print0)如下:

while IFS='' read -r -d '' filename; do
  : # something with "$filename"
done < <(find . -maxdepth 1 -type d -print0)

Another safe and robust approach is to have finditself directly invoke your desired command:

另一种安全可靠的方法是让find自己直接调用您想要的命令:

find . -maxdepth 1 -type d -exec printf '%s\n' '{}' +

See the UsingFindwiki page for a complete treatment of the subject.

有关该主题的完整处理,请参阅UsingFindwiki 页面。

回答by chepner

Since you aren't using any of the more advanced features of find, you can use a simple pattern to iterate over the subdirectories:

由于您没有使用 的任何更高级的功能find,您可以使用一个简单的模式来遍历子目录:

for i in ./*/; do
    echo "$i"
done

回答by Малъ Скрылевъ

You can do something like this:

你可以这样做:

find -maxdepth 1 -type d | while read -r i
do
    echo "$i"
done