迭代未扩展文件掩码的 $list
Iterate over a $list of unexpanded filemasks
我有一个 bash 脚本,它在软件发布期间 运行,用于验证所有源文件是否包含版权和许可 header。时不时地,我必须给它添加一个新的文件扩展名,因此我的 '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'
基本上有两个问题:
- 只有
echo
行生成任何输出; find
的实际调用是无声的,表明没有找到匹配的内容。这令人费解,因为回显版本表明 find
命令的构造完全符合我的预期。 (如果我 copy-paste 回显输出到 shell,它会 return 一个文件列表。)
for
循环扩展 $_fs 的值,在当前目录中有文件匹配 $_fs 的情况下(例如 'check-license.sh',对于 '* .sh') 然而,我想要的结果是让 $FILEMASKS 中的所有文件掩码进入我的 find
命令未展开。
[更新] 我刚刚找到了解决上面 #2 的方法:我从 FILEMASKS
中每个条目的开头删除了 *.
变量,然后在 find
命令中 原位 添加它。所以,只剩下#1。但我仍然有兴趣看到 #2 的其他解决方案。
您可以使用数组作为掩码列表来规避这些问题。
像这样:
#! /bin/bash
exts=('*.txt' '*.jpg')
for ext in "${exts[@]}" ; do
echo "* For mask [$ext]:"
find . -iname "$ext"
done
我得到了这个输出(顶层目录包含一个 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'
匹配且文件名中包含单引号的文件。 (并且由于 *
和其他通配字符未被引用,因此在将参数传递给 find
之前,您将通过 shell 通配。)
我有一个 bash 脚本,它在软件发布期间 运行,用于验证所有源文件是否包含版权和许可 header。时不时地,我必须给它添加一个新的文件扩展名,因此我的 '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'
基本上有两个问题:
- 只有
echo
行生成任何输出;find
的实际调用是无声的,表明没有找到匹配的内容。这令人费解,因为回显版本表明find
命令的构造完全符合我的预期。 (如果我 copy-paste 回显输出到 shell,它会 return 一个文件列表。) for
循环扩展 $_fs 的值,在当前目录中有文件匹配 $_fs 的情况下(例如 'check-license.sh',对于 '* .sh') 然而,我想要的结果是让 $FILEMASKS 中的所有文件掩码进入我的find
命令未展开。
[更新] 我刚刚找到了解决上面 #2 的方法:我从 FILEMASKS
中每个条目的开头删除了 *.
变量,然后在 find
命令中 原位 添加它。所以,只剩下#1。但我仍然有兴趣看到 #2 的其他解决方案。
您可以使用数组作为掩码列表来规避这些问题。
像这样:
#! /bin/bash
exts=('*.txt' '*.jpg')
for ext in "${exts[@]}" ; do
echo "* For mask [$ext]:"
find . -iname "$ext"
done
我得到了这个输出(顶层目录包含一个 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'
匹配且文件名中包含单引号的文件。 (并且由于 *
和其他通配字符未被引用,因此在将参数传递给 find
之前,您将通过 shell 通配。)