我有一个文件(tmp.txt),如下所示:
first
first rst
allrst
printf“first \ nfirst rst \ nallrst \ n”> tmp.txt;
我想要:
first rst
allrst
有没有办法搜索'rst',但是如果只在第一个中找到rst,则排除匹配?
我试过了:
awk '(/rst/ && /first/) || (/rst/ && !/first/)' tmp.txt
答案 0 :(得分:1)
使用grep
而不使用-P
选项:
grep 'rst' file | grep -v '^first$'
first rst
allrst
使用grep -P
grep -P '^(?!first$).*rst' file
first rst
allrst
答案 1 :(得分:0)
答案 2 :(得分:0)
或vks回答的变体
^(.*(?<!fi)rst.*)$
^ Start of string
( Capturing Group \1
. Any character except line break
* (zero or more)(greedy)
(?<! Negative Look-Behind
fi "fi"
) End of Negative Look-Behind
rst "rst"
. Any character except line break
* (zero or more)(greedy)
) End of Capturing Group \1
$ End of string
答案 3 :(得分:0)
Perl中的正则表达式为/^.*(?<!fi)rst.*/m
^ .*
(?<! fi )
rst .*
答案 4 :(得分:0)
您没有定义,rst
必须位于该行的末尾,因此这可能适用于您的要求:
grep -P '(?<!fi)rst' file
答案 5 :(得分:0)
这可能适合你(GNU sed):
sed 'h;s/first//g;/rst/!d;g' file
制作当前行的副本。删除所有first
并检查rst
的剩余行。如果字符串在更改的行中,则打印副本,否则删除该行。
答案 6 :(得分:0)
这符合您的所有要求:
perl -ne 'print if /^(?=.*first)(?=.*(?<!fi)rst)/; next if /first/; print if /rst/'
或者,正如你的标题所示,象征性地
perl -ne '
BEGIN {$x="rst"; $y="fi"; $z="(?<!fi)"}
print if /^(?=.*$y$x)(?=.*$z$x)/; next if /$y$x/; print if /$x/
'
答案 7 :(得分:0)
恕我直言,没有精确指定模式。如果该行包含afirst
或rstfirst
,该怎么办?所以我创建了两个版本。我假设每行包含字符串rst
。哪个不是,它不需要打印。我更喜欢awk针对perl的解决方案,因为后者使用了更多资源来启动,并且此任务并不真正需要。
第一个版本会检查包含rst
但不等于first
的所有字词。如果找到一个,则打印该行。
awk '/rst/ {
for(i=1;i<=NF&&$i~/rst/&&$i=="first";++i);
}i<=NF' inputfile
输入文件:
first
first rst
allrst
afirst
rstfirst
输出继电器:
first rst
allrst
afirst
rstfirst
另一个解决方案检查所有rst
,然后添加前两个字符(如果适用)。如果结果字符串不是first
,则它会打印该行。 (类似于sln
的负面后置缓冲区perl解决方案)
awk '/rst/ {
for(s=$0;i=index(s,"rst");s=substr(s,i+1))
if (i<2 || substr(s,i-2,5)!="first") {print; break}
}' inputfile
输出:
first rst
allrst
rstfirst
我希望这有点帮助!
答案 8 :(得分:0)
sed -n '1!{/rst/p}' tmp.txt
如果不在第一行,则打印与行中第一个模式匹配的匹配项,或者如果您想先计算第一个但不是第一个 - 仅当第一个也在另一个字符串中时:
sed -n '/[^f][^i]rst/p' tmp.txt
或者如果您想使用Bash shell,您可以更灵活地满足类似要求:
while read -r a; do
num_first=$(echo "$a" | grep -c 'first');
num_rst=$(echo "$a" | sed 's/first//g' | grep -c 'rst');
if [[ $num_rst+1 -gt $num_first ]]; then
echo "$a";
fi done < tmp.txt
此代码首先使用grep进行计数,然后使用rst进行计数 - 只有当rst首先超过字符串时才会打印字符串。
作为一个单行:
while read -r a; do num_first=$(echo "$a" | grep -c 'first');num_rst=$(echo "$a" | sed 's/first//g' | grep -c 'rst'); if [[ $num_rst+1 -gt $num_first ]]; then echo "$a"; fi done < myfile