首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何只打印在sed中出现的图案?

如何只打印在sed中出现的图案?
EN

Unix & Linux用户
提问于 2020-04-21 17:12:48
回答 1查看 300关注 0票数 0

我的Linux机器上有一些用分号分隔的数据。我需要找到Nth (例如3d)单词并打印它,而不是整行。我有下面的脚本,它找到了想要的模式,并将它放在_之间,因此我可以看到它正确地工作:

代码语言:javascript
复制
sed 's/\;[^;]*\;/_&_/3'

例如,对于此输入:

代码语言:javascript
复制
A1a 77l;a3sSs 2 smm;AS 3N123N8j a5njs;M3Xa 4 4a 3n1J  S2a;sm i;A9S;dd d3

它的产出如下:

代码语言:javascript
复制
A1a 77l;a3sSs 2 smm;AS 3N123N8j a5njs;M3Xa 4 4a 3n1J  S2a;sm i_;A9S;_dd d3

现在,当我已经找到模式时,我只想打印它而不是整行,以便输出如下:

代码语言:javascript
复制
A9S
EN

回答 1

Unix & Linux用户

回答已采纳

发布于 2020-04-21 18:05:23

代码语言:javascript
复制
sed -E 's/(([^;]*);){6}.*/\2/'

将执行此操作,其中6是要捕获的字段号。

(如果指定的字段号大于输入中的字段数,则它只是回显输入,而不执行任何替换。)

我使用了-E选项,它启用了扩展正则表达式。根据您拥有的sed版本,您可能需要使用-r。或者,跳过该选项,以便使用基本正则表达式,并转义括号和大括号:

代码语言:javascript
复制
sed 's/\(\([^;]*\);\)\{6\}.*/\2/'

的工作方式:

sed将在尽可能早的位置找到匹配,在这种情况下,从第一个字符开始就有匹配(假设输入中至少有6个字段)。外括号表达式匹配一个字段,后面跟着一个;分隔符。该命令将依次匹配这些命令的6 (或您指定的任何数字)。末端的.*与行的其余部分匹配。结果,整个行都被替换了。

用什么代替它呢?\2指的是内括号大小的表达式(以第二个左括号开头的表达式)。这个内括号表达式实际上被匹配了6次,但是sed将使用最后一个匹配,这就是您想要的。

功能更好的版本:

如果指定的字段不存在,则此版本将用空字符串替换整行(在示例中,如果输入中的字段少于6个):

代码语言:javascript
复制
sed -E 's/(([^;]*);){6}.*/\2/;t;d'

在OS版本的sed (或者一般的BSD?)上,这似乎需要写在两行上:

代码语言:javascript
复制
sed -E 's/(([^;]*);){6}.*/\2/;t
d'

如果进行了替换,命令t将终止sed对此输入行的处理。

因此,如果存在第6个字段,则将一如既往地进行替换,t命令将结束此输入行的处理。但是,如果第6个字段不存在,则s命令不会进行替换,因此t不会分支;sed只会继续到d命令,该命令将删除输入行(如果输入行中的字段少于6个,我们希望这样做)。

票数 3
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/581602

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档