在通用shell脚本中,我想使用shell模式匹配来过滤文本文件的行。
我在files.txt中有一个文件名列表:
file1.txt
file2.sh
file3.png
我在patterns.txt中有一个模式列表:
other_file.txt
file2.*
如果我在patterns.txt中有正则表达式,我可以这样做:
$ grep -v -f patterns.txt files.txt
但我想使用shell globbing模式。我找到了C函数fnmatch但没有使用shell / unix命令。
答案 0 :(得分:0)
好的,这将是非常不合格的,因为POSIX sh甚至没有数组(我会用它来缓存模式):
while IFS= read -r filename; do
hasmatch=0
while IFS= read -r pattern; do
case $filename in ($pattern) hasmatch=1; break ;; esac
done <patterns.txt
test $hasmatch = 1 || printf '%s\n' "$filename"
done <files.txt
如果您不需要位置参数($1
,$2
,...),您可以滥用这些参数进行模式缓存:
saveIFS=$IFS; IFS='
'; set -o noglob
set -- $(cat patterns.txt)
IFS=$saveIFS; set +o noglob
while IFS= read -r filename; do
hasmatch=0
for pattern in "$@"; do
case $filename in ($pattern) hasmatch=1; break ;; esac
done
test $hasmatch = 1 || printf '%s\n' "$filename"
done <files.txt
请注意那里的空白:我们将IFS
设置为文字换行符而不是其他内容,即IFS='
输入 '
。
我已经使用您的数据集加上一些附加内容(例如a b*
模式来测试空白行为)来测试它,并且根据OP中的规范它似乎对我有效。