迭代 glob 模式,而不是其中的文件

迭代 glob 模式,而不是其中的文件

我想对几组文件中的每一组执行相同的聚合操作,其中每一组文件都与一个全局模式匹配。我不想做的是将每个文件名分别通过管道传输到聚合函数中。

我的第一次尝试失败了,因为文件名在外循环中被通配,将整个集合扁平化为平面列表,而不是将它们视为单独的批次:

for fileglob in /path/to/bunch*1 /path/to/bunch*2 ... ; do
  stat "$fileglob" | awk [aggregation]
done

所以我*通过转义它来隐藏循环,然后对函数取消转义:

for fileglob in /path/to/bunch*1 /path/to/bunch*2 ... ; do
  realglob=`echo "$fileglob" | sed 's/\\//g'`
  stat "$realglob" | awk [aggregation]
done

一定有更好的方法。它是什么?

GNU bash,版本 3.2.51

答案1

这需要仔细使用引号:

for fileglob in '/path/to/bunch*1' '/path/to/bunch*2' ... ; do
    stat $fileglob | awk [aggregation]
done

但对于带有空格(或换行符)的文件名可能会失败。更好地使用这个:

fileglobs=("/path/to/bunch*1" "/path/to/bunch*2")

for aglob in "${fileglobs[@]}" ; do
    set -- $aglob
    stat "$@" | awk [aggregation]
done

glob 被正确扩展并放置在位置参数中:

set -- $aglob

然后,每个参数都作为参数放置stat在:

stat "$@"

并且 的输出stat(作为一个输出)到awk

答案2

将全局模式用单引号引起来,以避免在外循环中解释它们。

for fileglob in '/path/to/bunch*1' '/path/to/bunch*2' ; do
stat "$fileglob" | awk [aggregation]
done

我没有测试过这个,因为我不知道你想要完成什么,但我确实进行了类似的测试。

不带引号

for a in a* b*; do
echo $a
done

输出

$ ./test.sh
abc
ade
atlmfc.zip
bce
bin

带引号

for a in 'a*' 'b*'; do
echo $a
done

输出

$ ./test.sh
abc ade atlmfc.zip
bce bin

基本上,glob 由 echo 而不是循环来解释。因此有两行输出,每一行对应一个 glob。

相关内容