Regex grep/awk/perl/sed-打印所有与X匹配的行,忽略只有YX的行,并包括具有YX ZX的行
我有一个文件(tmp.txt),看起来像:Regex grep/awk/perl/sed-打印所有与X匹配的行,忽略只有YX的行,并包括具有YX ZX的行,regex,perl,awk,sed,grep,Regex,Perl,Awk,Sed,Grep,我有一个文件(tmp.txt),看起来像: first first rst allrst printf“first\nfirst\nallrst\n”>tmp.txt 我想: first rst allrst 是否有任何方法可以搜索“rst”,但如果仅在第一个中找到rst,则排除匹配 我试过: awk '(/rst/ && /first/) || (/rst/ && !/first/)' tmp.txt ^(?=.*? 在Perl中试试这个。参见演
first
first rst
allrst
printf“first\nfirst\nallrst\n”>tmp.txt
我想:
first rst
allrst
是否有任何方法可以搜索“rst”,但如果仅在第一个中找到rst,则排除匹配
我试过:
awk '(/rst/ && /first/) || (/rst/ && !/first/)' tmp.txt
^(?=.*?
在Perl中试试这个。参见演示
使用grep
而不使用-p
选项:
grep 'rst' file | grep -v '^first$'
first rst
allrst
使用grep-p
grep -P '^(?!first$).*rst' file
first rst
allrst
还是vks答案的一个变体
^(.*(?<!fi)rst.*)$
^(.*?
^字符串的开头
(正在捕获组\1)
.除换行符外的任何字符
*(零或更多)(贪婪)
(?Perl中的正则表达式应该是/^.*
^.*
(?您没有定义,因此rst
必须位于行的末尾,因此这可能适用于您的要求:
grep -P '(?<!fi)rst' file
grep-P'(?这可能适合您(GNU-sed):
制作当前行的副本。首先删除所有,
,然后检查剩余行的rst
。如果字符串位于更改的行中,则打印副本,否则删除该行。这符合您的所有要求:
perl -ne 'print if /^(?=.*first)(?=.*(?<!fi)rst)/; next if /first/; print if /rst/'
perl-ne'print if/^(?=.*first)(?=)*(?I模式没有精确指定。如果行包含affirst
或rstffirst
,应该怎么做?因此我创建了两个版本。我假设每行包含字符串rst
。不需要打印。我更喜欢使用解决方案,因为后者需要更多的资源来启动和打印此任务实际上不需要
第一个版本检查所有包含rst
,但不等于first
的单词。如果找到一个,则打印该行
awk '/rst/ {
for(i=1;i<=NF&&$i~/rst/&&$i=="first";++i);
}i<=NF' inputfile
输出:
first rst
allrst
afirst
rstfirst
另一个解决方案检查所有rst
,然后添加前两个字符(如果适用)。如果结果字符串不是第一个
,则它将打印该行。(类似于sln
的负查找缓冲区解决方案)
我希望这有点帮助
sed -n '1!{/rst/p}' tmp.txt
如果不在第一行,则打印与行中图案rst的匹配项,或者如果要单独计算rst而不是第一行-仅当rst也在另一个字符串中时:
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
读取时-ra;do
num_first=$(echo“$a”| grep-c“first”);
num_rst=$(回显“$a”| sed's/first//g'| grep-c'rst”);
如果[$num_rst+1-gt$num_first]];则
回音“$a”;
fi done
这段代码首先使用grep进行计数,然后使用rst-只有当rst的长度大于字符串的长度时,才会打印字符串
作为一个班轮:
read-ra;do num_-first=$(echo“$a”| grep-c'first”);num_-rst=$(echo“$a”| sed's/first//g'| grep-c'rst”);如果[$num_-rst+1-gt$num_-first]],则echo“$a”fi done
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
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
sed -n '1!{/rst/p}' tmp.txt
sed -n '/[^f][^i]rst/p' tmp.txt
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