【问题标题】:Bash Script - iterating over output of findBash 脚本 - 迭代 find 的输出
【发布时间】:2014-03-06 22:49:27
【问题描述】:

我有一个 bash 脚本,我需要在其中迭代 find 命令输出的每一行,但似乎我正在迭代 find 命令中的每个 Word(空格分隔)。到目前为止,我的脚本看起来像这样:

folders=`find -maxdepth 1 -type d`

for $i in $folders
do
    echo $i
done

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

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

但我很想得到这样的输出:

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

我在这里做错了什么?

【问题讨论】:

标签: linux bash shell scripting


【解决方案1】:

你可以这样做:

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

【讨论】:

  • 不安全。不能正确处理包含反斜杠序列、换行符、多个空白字符的运行等的文件名。
  • @CharlesDuffy 修复并检查了``和空格
  • ...更好 -- 使用 -r,您已经处理了反斜杠序列,但您仍在扩展 glob,将空格压缩为单个字符,并去除尾随空格。跨度>
  • @CharlesDuffy 如何查看?我检查了两个空格,它可以处理
  • 检查如何?您在这里仍然遇到的问题是连续两个空格,而不是文件名中的任何地方的两个空格。
【解决方案2】:
folders=`foo`

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

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

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

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

请参阅UsingFind wiki 页面以获取对该主题的完整处理。

【讨论】:

  • 请注意,find ... -exec 形式仅适用于普通命令——如果您想使用 shell 内置函数、shell 函数、复合命令等,您需要使用 while ... done 方法或 @ 987654329@ loop chepner 建议。
  • @GordonDavisson 一般正确。但是,UsingFind wiki 页面(在我的答案中链接)描述了使用 -exec bash -c '...' _ {} +,它允许使用 shell 内置函数等。
【解决方案3】:

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

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

【讨论】:

  • 大多数答案都在谈论使用 while。但是,我试图找到一个只涉及 for 循环的解决方案,并且您的解决方案效果很好。我的场景是从不同的文件夹中获取文件名。因此,对此添加了一个小改动:(cd $folder; for i in ./*/; do echo "$i"; done)。创建了一个子shell,用于在我的shell上运行它而无需更改文件夹路径
猜你喜欢
  • 2015-06-17
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 2010-09-20
  • 2017-11-21
  • 2017-06-15
  • 2018-05-18
相关资源
最近更新 更多