【问题标题】:How to join several consecutive lines using one pattern for the first line and the other pattern for all following lines, preferably with sed?如何使用第一行的一个模式和所有后续行的另一个模式连接几条连续的行,最好使用 sed?
【发布时间】:2015-10-24 03:54:21
【问题描述】:

我想从这个例子中删除整个“派生词”部分,两者都是。到目前为止,我已经想出了将“派生词:”这一行之后的行与该行合并并删除它的想法,但我不能只合并以下两行,行数可能因文章而异。所以,我的想法是检查行是否与模式“^Derived words:”匹配,然后检查下一行是否与模式“^[a-z]”匹配,如果为真,连接在一起,检查下一行......听起来这项工作是完美定制的对于 Bash 的 if-then-else,但如果可能的话,我更喜欢纯 sed 解决方案。

A swift event or process happens very quickly or without delay.
Our task is to challenge the UN to make a swift decision... 
The police were swift to act. 
Syn:
quick
Derived words:
swiftly  The French have acted swiftly and decisively to protect their industries. 
swiftness  The secrecy and swiftness of the invasion shocked and amazed army officers. 
  Something that is swift moves very quickly.
With a swift movement, Matthew Jerrold sat upright. 
Syn:
quick
Derived words:
swiftly  ^[[0;37m...a swiftly flowing stream. 
swiftness  With incredible swiftness she ran down the passage. 
  A swift is a small bird with long curved wings.

预期结果

A swift event or process happens very quickly or without delay.
Our task is to challenge the UN to make a swift decision... 
The police were swift to act. 
Syn:
quick
  Something that is swift moves very quickly.
With a swift movement, Matthew Jerrold sat upright. 
Syn:
quick
  A swift is a small bird with long curved wings.

提前致谢

【问题讨论】:

  • 重要的是定义关闭Derived words: 块的内容。这可以通过正则表达式定义吗?我看到你选择的下一个词是“快速移动……”,这是为什么呢?试着自己回答这个答案并做一些尝试!
  • "With a swift movement..." 是一个用法示例,应该保持原样。

标签: regex bash sed


【解决方案1】:

这可能对你有用(GNU sed):

sed -n '/^Derived words:/{:a;n;/^\w/ba};p' file

使用 seds 类似 grep 的标志 -n 并在遇到 Derived words: 时继续阅读,直到在行首匹配一个非单词。

【讨论】:

  • 谢谢,它有效,我需要在一大堆单词上检查它,并希望这些模式是一致的。我猜 \w 等于小写字母的任意组合。换句话说,它和 [a-z]\+ 一样吗?
【解决方案2】:

我发现当你想处理多行的块时,最好的工具往往是 awk,例如:

awk '/^Derived words/{skip=1} /^ /{skip=0} 1{if(!skip)print}' input

A swift event or process happens very quickly or without delay.
Our task is to challenge the UN to make a swift decision...
The police were swift to act.
Syn:
quick
  Something that is swift moves very quickly.
With a swift movement, Matthew Jerrold sat upright.
Syn:
quick
  A swift is a small bird with long curved wings.

【讨论】:

  • 你可以把这个1{if(!skip)print}'改成!skip
  • 确实,awk '/^Derived words/{skip=1} /^ /{skip=0} !skip' 也可以,谢谢
  • 更改后的变体完成了这项工作,原来的没有。
【解决方案3】:

这应该在常规(非 GNU)sed 中工作。可能有办法消除冗余模式,但我还没有想出。

sed -e :a -e '/^Derived words:/N;s/\n[a-z]//;ta' -e 's/^Derived words:.*\n//'

它是这样工作的:

  • 您说过要删除“派生词:”以及任何以字母开头的行(我们称之为续行)。
  • 因此 sed 像往常一样读取输入并将其逐行回显到标准输出。
  • 但是当它在一行的开头遇到“派生词:”时,在回显它之前,它会将下一行读入模式空间并附加到“派生词:”,用换行符分隔它们(N 命令),因为它看到“派生词:”,仍然没有任何回应。然后它会尝试删除该换行符和紧随其后的字母字符(s 命令)。

    • 如果可以,那么它一定找到了续行,因此它会尝试再次执行此操作,方法是跳转到脚本的开头(t 命令,它有条件地跳转到前面定义的标签“a”冒号命令),它将在其中追加下一行,依此类推。
    • 如果不能,则留下“派生词:”行以及附加的任何续行(不包括已删除的换行符)加上下一个非续行,即用换行符与其余部分分隔。
  • 1234563下一个非连续行——它与之呼应。然后它继续处理下一行的输入。

【讨论】:

    猜你喜欢
    • 2021-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-12
    • 2021-08-17
    • 1970-01-01
    • 2011-11-05
    相关资源
    最近更新 更多