对于文件列表,我想匹配那些不以.txt
结尾的文件。我目前正在使用这个表达式:
.*(txt$)|(html.txt$)
这个表达式将匹配以.txt
结尾的所有内容,但我希望它做相反的操作。
应匹配:
happiness.html
joy.png
fear.src
应该而不是匹配:
madness.html.txt
excitement.txt
我想得到这个,这样我就可以和fswatch:一起使用了
fswatch -0 -e 'regex here' . | xargs -0 -n 1 -I {} echo "{} has been changed"
问题是它似乎不起作用。
附言:我使用标签bash而不是fswatch,因为我没有足够的信誉点来创建它。对不起!
尝试使用一个lookbacking,如下所示:
.*$(?<!.txt)
演示
基本上,只要最后4个字符不是".txt"
,它就匹配任何一行文本。
您可以为此使用负前瞻。
^(?!.*.txt).+$
实时演示
您可以使用选项-P
:将此表达式与grep一起使用
grep -Po '^(?!.*.txt).+$' file
由于问题已标记为bash
,可能不支持lookahead(grep -P
除外),因此这里有一个不需要lookahead的grep
解决方案:
grep -v '.txt$' file
happiness.html
joy.png
fear.src
编辑:您可以使用此xargs
命令来避免匹配*.txt
文件:
xargs -0 -n 1 -I {} bash -c '[[ "{}" == *".txt" ]] && echo "{} has been changed"'
这实际上取决于您使用的正则表达式工具。许多工具提供了一种颠倒正则表达式含义的方法。例如:
猛击
# succeeds if filename ends with .txt
[[ $filename =~ "."txt$ ]]
# succeeds if filename does not end with .txt
! [[ $filename =~ "."txt$ ]]
# another way of writing the negative
[[ ! $filename =~ "."txt$ ]]
grep
# succeeds if filename ends with .txt
egrep -q ".txt$" <<<"$filename"
# succeeds if filename does not end with .txt
egrep -qv ".txt$" <<<"$filename"
awk
/.txt$/ { print "line ends with .txt" }
! /.txt$/ { print "line doesn't end with .txt" }
$1 ~ /.txt$/ { print "first field ends with .txt" }
$1 !~ /.txt$/ { print "first field doesn't end with .txt" }
对于喜欢冒险的人来说,posix ERE将在任何posix兼容的正则表达式引擎中工作
/[^t]$|[^x]t$|[^t]xt$|[^.]txt$/