带有 fswatch 的正则表达式 - 排除不以 ".txt" 结尾的文件



对于文件列表,我想匹配那些不以.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$/

最新更新