迭代一个未扩展的文件掩码列表

时间:2015-01-25 06:52:26

标签: bash for-loop

我有一个在软件发布期间运行的bash脚本,用于验证所有源文件是否包含版权和版权。许可证标题。我不时地为它添加一个新的文件扩展名,因此我的'find'命令变得有点笨拙。我决定稍微重构一下,以便更容易添加新的文件类型。我想通过定义包含文件掩码列表的变量FILEMASKS来实现此目的。从概念上讲,它看起来像这样:

FILEMASKS="*.?pp *.[ch] *.sh"
echo FILEMASKS is \'$FILEMASKS\'

for _fs in $FILEMASKS; do
  echo \# find . -iname \'$_fs\'  # debug
          find . -iname \'$_fs\'  # (not really indented this way)
done

上述代码的输出不符合我的预期:

FILEMASKS is '*.?pp *.[ch] *.sh'
# find . -iname '*.?pp'
# find . -iname '*.[ch]'
# find . -iname 'check-license.sh'

基本上,有两个问题:

  1. 只有echo行生成任何输出; find的实际调用是静默的,表示没有找到匹配的内容。这很令人费解,因为echo'd版本表明find命令的构建正是我所期望的。 (如果我将回显输出复制粘贴到shell,它会返回一个文件列表。)
  2. for循环正在扩展$ _fs的值,如果当前目录中的文件与$ _fs匹配(例如'check-license.sh','* .sh ')我想要的结果是让$ FILEMASKS中的所有文件掩码都使我的find命令无法扩展。
  3. [更新] 我刚刚找到了解决#2的方法:我从*.变量中的每个条目的开头删除FILEMASKS,然后添加它在find命令中返回 in situ 。所以,只剩下#1了。但我仍然有兴趣看到#2的其他解决方案。

1 个答案:

答案 0 :(得分:2)

您可以使用数组作为掩码列表来规避这些问题。

这样的事情:

#! /bin/bash
exts=('*.txt' '*.jpg')

for ext in "${exts[@]}" ; do
  echo "* For mask [$ext]:"
  find . -iname "$ext"
done

我得到这个输出(toplevel目录包含一个txt和一个jpg文件,以确保没有早期的globbing发生):

* For mask [*.txt]:
./b.txt
./bar/a.txt
* For mask [*.jpg]:
./foo/a.jpg
./b.jpg

你的问题#1是这样的:

$ find . -iname '*.txt'
./a.txt
$ find . -iname \'*.txt\'
$ touch "'b.txt'"
$ find . -iname \'*.txt\'
./'b.txt'

您要求find列出文件名中匹配'*.?pp'的文件与文件名中的单引号。 (并且因为*和其他的globbing字符没有被引用,所以在参数传递给find之前,你将通过shell进行通配。)