我想对几组文件中的每一组执行相同的聚合操作,其中每一组文件都与一个全局模式匹配。我不想做的是将每个文件名分别通过管道传输到聚合函数中。
我的第一次尝试失败了,因为文件名在外循环中被通配,将整个集合扁平化为平面列表,而不是将它们视为单独的批次:
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。