我想遍历一个文件列表。这个列表是一个find命令的结果,所以我想出了:

getlist() {
  for f in $(find . -iname "foo*")
  do
    echo "File found: $f"
    # do something useful
  done
}

这很好,除非文件名称中有空格:

$ ls
foo_bar_baz.txt
foo bar baz.txt

$ getlist
File found: foo_bar_baz.txt
File found: foo
File found: bar
File found: baz.txt

我能做些什么来避免空格分割?


当前回答

find . -iname "foo*" -print0 | xargs -L1 -0 echo "File found:"

其他回答

find . -name "fo*" -print0 | xargs -0 ls -l

见xargs先生。

我最近不得不处理一个类似的情况,我构建了一个FILES数组来遍历文件名:

eval FILES=($(find . -iname "foo*" -printf '"%p" '))

这里的想法是用双引号包围每个文件名,用空格分隔它们,并使用结果初始化FILES数组。 必须使用eval来正确计算find输出中的双引号,以初始化数组。

要遍历文件,只需执行:

for f in "${FILES[@]}"; do
    # Do something with $f
done
find . -iname "foo*" -print0 | xargs -L1 -0 echo "File found:"

因为你没有使用find做任何其他类型的过滤,你可以使用以下bash 4.0:

shopt -s globstar
getlist() {
    for f in **/foo*
    do
        echo "File found: $f"
        # do something useful
    done
}

**/将匹配零个或多个目录,因此完整模式将匹配当前目录或任何子目录中的foo*。

还有一个非常简单的解决方案:依赖bash globbing

$ mkdir test
$ cd test
$ touch "stupid file1"
$ touch "stupid file2"
$ touch "stupid   file 3"
$ ls
stupid   file 3  stupid file1     stupid file2
$ for file in *; do echo "file: '${file}'"; done
file: 'stupid   file 3'
file: 'stupid file1'
file: 'stupid file2'

注意,我不确定这个行为是默认的,但我在我的商店里没有看到任何特殊的设置,所以我会说它应该是“安全的”(在osx和ubuntu上测试过)。