从man grep
:
-o, --only-matching
Print only the matched (non‐empty) parts of a matching line, with each such part on a separate output line.
一个简单的问题:如何仅打印匹配行的匹配(非空)部分,并且每个此类部分都在同一输出行上?
从man grep
:
-o, --only-matching
Print only the matched (non‐empty) parts of a matching line, with each such part on a separate output line.
一个简单的问题:如何仅打印匹配行的匹配(非空)部分,并且每个此类部分都在同一输出行上?
以下是使用 Perl 语句完成这项工作的一种方法:
解释:
使用 grep 和 awk 的另一种可能的解决方案:
即:
grep -on foo file --> 匹配模式 foo 并在输出的每一行前面加上输入文件中基于 1 的行号。如果有多个匹配项,则重复相同的行号,例如:
awk:
-F ":"
--> 考虑冒号作为分隔符来解析字段s != $1 || NR==1
--> 检查变量是否s
与第一个字段的值不同或正在分析的行是第一个字段。如果为 true,请执行以下操作:s=$1;
--> 变量 s 取第一个字段的值(行号)if(p){print p};
--> 如果变量p
被赋值,则打印它p=$2;
--> 变量p
取第二个字段的值(匹配模式)next
--> 进入下一次迭代,并开始重新评估s != $1 || NR==1
下一行的条件{p=p" "$2;}
--> 如果第 2 步的条件为 false(当行号与前一行相同时:同一行上有多个匹配),则变量p
将其自身值连接到该行的第二个字段(匹配模式)正在分析(它们之间有空格)。END{print p}
--> 最后,分析完所有行后,打印变量 p 中保存的最后一个值。因此,在上面的情况下:
第 1 行-->
1:foo
被分析:条件为真,因为NR==1
。s
取 vale1
,p
未赋值,因此不打印, p 取值 foo ,继续分析第二行。第 2 行-->
1:foo
被分析:条件为 false,因为 s==$1(该行的第一个字段是 = 1,变量s
来自1
上一步)和 NR==2(我们在第二行)。因此,我们继续执行{p=p" "$2;}
,变量p
取自身值 + " " + $2 (即foo
),成为foo foo
第 3 行-->
3:foo
进行分析:条件为真,因为s!=$1
(确实s
是1
第三行的第一个字段是3)。s
取 vale3
,p
被赋值(foo foo
来自上一步),因此被打印,p
取值foo
,继续分析第 4 行第 4行-->
3:foo
被分析:条件为 false,因为 s==$1 (此字段的第一个字段)行 = 3,变量s
来自3
上一步)和 NR==4(我们在第四行)。因此,我们继续执行{p=p" "$2;}
,变量p
取自身值 + " " + $2 (即foo
),成为foo foo
第 5 行-->
3:foo
进行分析:条件为 false,因为 s==$1 (该行的第一个字段是 = 3变量s
是3
从步骤 3 开始)并且 NR==5(我们在第 5 行)。因此,我们继续执行{p=p" "$2;}
,变量p
取自身值(即上一步中的 'foo foo')+ " " + $2 (即foo
),成为foo foo foo
END --> 没有更多的行需要分析。
END
因此执行之后的部分,并打印{print p}
变量p
(现在包含上一步中的 , )。foo foo foo
最终输出: