我的Linux机器上有一些用分号分隔的数据。我需要找到Nth (例如3d)单词并打印它,而不是整行。我有下面的脚本,它找到了想要的模式,并将它放在_之间,因此我可以看到它正确地工作:
sed 's/\;[^;]*\;/_&_/3'例如,对于此输入:
A1a 77l;a3sSs 2 smm;AS 3N123N8j a5njs;M3Xa 4 4a 3n1J S2a;sm i;A9S;dd d3它的产出如下:
A1a 77l;a3sSs 2 smm;AS 3N123N8j a5njs;M3Xa 4 4a 3n1J S2a;sm i_;A9S;_dd d3现在,当我已经找到模式时,我只想打印它而不是整行,以便输出如下:
A9S发布于 2020-04-21 18:05:23
sed -E 's/(([^;]*);){6}.*/\2/'将执行此操作,其中6是要捕获的字段号。
(如果指定的字段号大于输入中的字段数,则它只是回显输入,而不执行任何替换。)
我使用了-E选项,它启用了扩展正则表达式。根据您拥有的sed版本,您可能需要使用-r。或者,跳过该选项,以便使用基本正则表达式,并转义括号和大括号:
sed 's/\(\([^;]*\);\)\{6\}.*/\2/'sed将在尽可能早的位置找到匹配,在这种情况下,从第一个字符开始就有匹配(假设输入中至少有6个字段)。外括号表达式匹配一个字段,后面跟着一个;分隔符。该命令将依次匹配这些命令的6 (或您指定的任何数字)。末端的.*与行的其余部分匹配。结果,整个行都被替换了。
用什么代替它呢?\2指的是内括号大小的表达式(以第二个左括号开头的表达式)。这个内括号表达式实际上被匹配了6次,但是sed将使用最后一个匹配,这就是您想要的。
如果指定的字段不存在,则此版本将用空字符串替换整行(在示例中,如果输入中的字段少于6个):
sed -E 's/(([^;]*);){6}.*/\2/;t;d'在OS版本的sed (或者一般的BSD?)上,这似乎需要写在两行上:
sed -E 's/(([^;]*);){6}.*/\2/;t
d'如果进行了替换,命令t将终止sed对此输入行的处理。
因此,如果存在第6个字段,则将一如既往地进行替换,t命令将结束此输入行的处理。但是,如果第6个字段不存在,则s命令不会进行替换,因此t不会分支;sed只会继续到d命令,该命令将删除输入行(如果输入行中的字段少于6个,我们希望这样做)。
https://unix.stackexchange.com/questions/581602
复制相似问题