在 Sed 中搜索名称前面的单词

在 Sed 中搜索名称前面的单词

该线程的动机是在此线程的链接中找到的算术命令这里在塞德.所以我想在 Sed 中进行向后算术。

数据

Mikael symptom
David symptom
hello symptom

命令应返回前两个条目。 Perl 中的后视是一种方法,但我想看看 Sed 是否可以做到这一点。

伪代码中的一种方法

  • 匹配名称:g/[A-Z]\w\w/;中的单词is.words[2]('symptom')

向后看

  • 匹配symptom;查找后面的名称。返回如果名称。

你能在 Sed 中写出这段伪代码吗?

答案1

sed '/^[[:upper:]][[:lower:]]\{1,\} symptom$/!d
    H;x;/^\n/!q;s///;x;d'

这将查找以大写字符开头,后跟一个或多个小写字符的行,然后仅查找一个<空格>和字符串症状。如果当前行不匹配,则会将其d删除,并且脚本会从顶部重新开始下一个输入行。

如果它匹配它被复制到H插入的行分隔符后面的旧空间\n。第一次发生这种情况时,h旧空间将是空的 - 因此主角将是一个\newline。匹配行被Hld 后,h旧的和模式空间被 ex改变。如果有!不是\n当时模式空间中的领先ewline 然后sed quits 输入 - 突然停止读取更多输入(或在其脚本中执行任何更多命令 - 例如d根本不。但是,当存在前导\n行被删除并且h旧的和模式空间再次被x改变并且模式空间被d删除时。

结果是第一个遇到的行被保留,并且其表示的第一次出现标记将其从quitting 输入中保存下来,但是第二当它发生时结束处理。

但也许我误解了?我理解你的意思是你只想要文件中的前两个匹配项。

如果你只想要姓名如果症状$这很简单:

sed -n '/^[[:upper:]][[:lower:]]\{1,\} [^ ]*$/s/ symptom$//p'

在这里,我们只是验证我们确实正在寻找一个可能在尝试s///替换之前匹配行 - 因为s///替换是功能父地址。如果为真,我们会尝试修剪不需要的尾部,并且仅p在成功时才进行打印 - 所以两个都在我们之前验证线头和尾部条件。

答案2

据我了解,您想要打印任何包含大写单词且紧随其后的单词的行symptom。在这种情况下:

$ sed -rn '/\b[[:upper:]][[:lower:]]*[[:space:]]+symptom/p' data
Mikael symptom
David symptom

为了方便起见,我使用了\bwhich来表示单词边界。这至少是 GNU sed 支持的。如果您的 sed 不支持,请告诉我。

怎么运行的:

基本形式是:

sed -n '/pattern/p' file

这仅打印匹配的行pattern。在我们的例子中,该模式包括:

  • \b

    这仅在单词边界匹配。

  • [[:upper:]][[:lower:]]*

    这匹配一个大写字母后跟零个或多个小写字母。

    请注意,在古代,这可能是这样写的[A-Z][a-z]+。由于 unicode,现在这是不可靠的。上面使用字符类upperlower因此是 unicode 安全的。

  • [[:space:]]+symptom

    这与后跟单词 的一个或多个空格匹配symptom

选择

假设您只想打印前面的名称symptom

$ sed -rn 's/\b([[:upper:]][[:lower:]]*)[[:space:]]+symptom.*/\1/p' data
Mikael
David

答案3

sed -n '/^[[:upper:]]\w* symptom/s/ .*//p'

打印以大写单词开头的行,symptom然后删除除第一个单词之外的所有内容。

相关内容