文件:
string1 string2 string3 string4 string5 string6
string3 string1 string2 string4 string5 string6
string6 string3 string2 string4 string1 string5
期待:
string2 string3 string4 string5
string2 string4 string5
string2 string4 string1 string5
匹配模式=如何string1
打印匹配行但仅从string2
到string5
?awk
不幸的是,这不符合流程:
awk '/string2/,/string5/' file
我们假设在不同的地方有几条带有string2
和的长线。string5
答案1
您可以使用 awkindex
和match
函数,例如
awk 'match($0,/string5/) {
START2 = index($0,"string2");
print substr($0,START2,RSTART+RLENGTH-START2)
}' file
前任。
$ mawk 'match($0,/string5/) {
START2 = index($0,"string2");
print substr($0,START2,RSTART+RLENGTH-START2)
}' file
string2 string3 string4 string5
string2 string4 string5
string2 string4 string1 string5
请注意,这假设在存在的string2
每一行中都存在string5
- 如果不是这种情况,您将需要检查的值index($0,"string2")
并采取相应措施。
答案2
实际上,您要做的就是迭代每个字段,并在找到结果时使用变量“启用”打印。因此,您需要一个标志变量和 for 循环:
$ cat file.txt
string1 string2 string3 string4 string5 string6
string3 string1 string2 string4 string5 string6
string6 string3 string2 string4 string1 string5
$ awk '{flag=0;for(i=1;i<=NF;i++){ if($i=="string2") flag=1; if($i=="string6") flag=0; if(flag)printf "%s%s",$i,FS;};print"";}' file.txt
string2 string3 string4 string5
string2 string4 string5
string2 string4 string1 string5
这里发生的情况是,整个代码块将针对每一行运行。在每一行上,我们从第一个字段迭代到最后一个字段。首先,我们将标志变量设置为 0,然后继续检查每个字段。如果字段包含所需的“string2”,则标志将设置为 1,如果它是“string6”(这是我们想要停止的那个)- 标志将设置为 0;最后,if 语句将检查是否设置了标志并打印当前字段并附加字段分隔符(由 FS 变量表示)。打印完所有内容后,我们还通过print ""
命令插入换行符。
如果有不匹配的行,上述命令将打印空行。您可以通过添加搜索模式来缓解这种情况,这将仅在字符串中找到模式时才限制代码块的执行:
$ cat file.txt
string1 string2 string3 string4 string5 string6
blah blah
string3 string1 string2 string4 string5 string6
string6 string3 string2 string4 string1 string5
$ awk '$0~"string2"{flag=0;for(i=1;i<=NF;i++){ if($i=="string2") flag=1; if(flag)printf "%s%s",$i,FS;};print"";}' file.txt
string2 string3 string4 string5 string6
string2 string4 string5 string6
string2 string4 string1 string5
或者,我们可以使用额外的变量来获得相同的结果:
$ awk '{j=0;f=0;for(i=1;i<=NF;i++){if($i=="string2"){j=1;f=1};if(f)printf "%s%s",$i,FS;};if(j)print"";}' file.txt
string2 string3 string4 string5 string6
string2 string4 string5 string6
string2 string4 string1 string5
答案3
首先,您只保留包含 和 的行string2
,且string5
这些行的顺序与特定顺序一致(第 1 行中的模式)。接下来,您要做的就是删除 和 之前string2
以及 之后的所有内容string5
(第 2 行和第 3 行),最后打印剩余的内容。
awk '/string2 .* string5/ {
sub(/^.*string2/, "string2", $0);
sub(/string5.*$/, "string5", $0);
print $0;
}'
答案4
使用 grep:
grep -Po '\bstring2.*string5\b' file.txt