如何从shell使用fnmatch? [英] How to use fnmatch from a shell?

查看:40
本文介绍了如何从shell使用fnmatch?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在通用的shell脚本中,我想使用shell模式匹配来过滤文本文件的行.

In a generic shell script, I would like to use shell pattern matching to filter the lines of a text file.

我在files.txt中有一个文件名列表:

I have a list of file names in files.txt:

file1.txt
file2.sh
file3.png

我在patterns.txt中有一个模式列表:

And I have a list of patterns in patterns.txt:

other_file.txt
file2.*

如果我在patterns.txt中有正则表达式,我可以这样做:

If I would have regular expressions in patterns.txt, I could do this:

$ grep -v -f patterns.txt files.txt

但是我想使用Shell Globing模式.我找到了C函数fnmatch,但没有使用它的shell/unix命令.

But I would like to use shell globbing patterns. I found the C function fnmatch but no shell/unix command to use it.

推荐答案

好的,这真的很糟糕,因为POSIX sh甚至没有数组(我本该用于缓存模式):

OK, this is going to be really unperformant, as POSIX sh does not even have arrays (which I would have used for caching the patterns):

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,...),则可以通过以下方式将其用于模式缓存:

If you don’t need the positional arguments ($1, $2, …) you can abuse those for pattern caching though:

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=' Enter '.

Be careful about whitespace there though: we set IFS to a literal newline character and nothing else, i.e. IFS='Enter'.

我已经使用您的数据集对它进行了测试,并添加了一些附加内容(例如a b*模式,以测试空白行为),并且根据OP中的规范,它似乎对我有用.

I’ve tested this with your dataset plus a few additions (like a a b* pattern, to test whitespace behaviour), and it seems to work for me according to the spec in the OP.

这篇关于如何从shell使用fnmatch?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆