【问题标题】:If pattern matched delete newline character in that line如果模式匹配删除该行中的换行符
【发布时间】:2014-11-14 15:34:12
【问题描述】:

假设模式是字符串“Love”

输入

This is some text
Love this or that
He is running like a rabbit

输出

This is some text
Love this or thatHe is running like a rabbit

我注意到 sed 对于删除换行符非常不愉快,知道吗?

【问题讨论】:

  • sed 一次处理一行。每次它开始在一行上工作时,它都会删除新行并将其放置在模式空间中。模式空间是所有动作发生的地方。替换完成后,它会放置换行符并打印到STDOUT。要删除新行,您需要使用 N 将下一行附加到由 \n 分隔的模式空间,然后您可以使用替换删除。
  • 你喜欢thatHe之间的空格吗?

标签: awk sed grep tr


【解决方案1】:

Perl:

$ perl -pe 's/^(Love[^\n]*)\n/\1/' file.txt
This is some text
Love this or thatHe is running like a rabbit

或者,如果意图只关注\n,您可以基于模式chomp

$ perl -pe 'chomp if /^Love/' file.txt
This is some text
Love this or thatHe is running like a rabbit

【讨论】:

    【解决方案2】:

    这是另一个awkvariation:

    awk '{ORS=(/Love/?FS:RS)}1' file
    This is some text
    Love this or that He is running like a rabbi
    

    这会根据模式更改ORS


    这里有一些其他的awk

    awk '{printf "%s%s",$0,(/Love/?FS:RS)}' file
    This is some text
    Love this or that He is running like a rabbit
    

    如果行中有Love,则使用FS 作为分隔符,否则使用RS

    这也应该可以,但使用第一个。

    awk '{printf "%s"(/Love/?FS:RS),$0}' file
    

    【讨论】:

    • 如果你不喜欢两行之间的空格,使用awk '{ORS=(/Love/?"":RS)}1' 甚至可以使用:awk 'ORS=(/Love/?FS:RS)'
    【解决方案3】:

    通过 Perl,

    $ perl -pe 's/^Love.*\K\n//' file
    This is some text
    Love this or thatHe is running like a rabbit
    

    \K 丢弃以前匹配的字符。

    $ perl -pe '/^Love/ && s/\n//' file
    This is some text
    Love this or thatHe is running like a rabbit
    

    如果一行以字符串Love 开头,则从该行中删除换行符。

    【讨论】:

    • 如果只需要删除换行符,请使用chompperl -pe 'chomp if /^Love/' file
    【解决方案4】:

    你可以用这个:

    sed '/^Love/{N;s/\n//;}' love.txt
    

    详情:

    /^Love/ 标识要处理的行,如果您愿意,可以使用 /[Ll]ove/ 代替

    N 将下一行添加到模式空间。在这个命令之后,模式空间包含Love this or that\nHe is running like a rabbit

    s/\n// 替换换行符

    【讨论】:

    • 只会说哇,解释起来很简单,{ } 需要使用关键元素 N @casimir-et-hippolyte
    • @josifoski:大括号括起当条件/^Love/ 为真时要执行的操作。
    • 请注意,在第一次匹配和替换之后,模式空间不会在由于 N 而被拉入的下一行之前包含换行符,因此如果您在下一行的开头,它将不匹配。例如。考虑输入文件“Love\nLove\nLove”会发生什么。第二个爱永远不会匹配。
    • @SomeGuy:sed ':a;/[Ll]ove[^\n]*$/{N;ba};s/\n//g' love.txt 通过一个简单的循环来解决问题,在替换之前附加每个连续的匹配行(这次是全局的)。
    【解决方案5】:
    $ awk '/Love/{printf "%s ",$0;next} 1' file
    This is some text
    Love this or that He is running like a rabbit
    

    解释:

    • /Love/{printf "%s ",$0;next}

      对于包含Love 的行,该行通过printf 打印,不带换行符。 awk 然后在 next 行重新开始。

    • 1

      对于不包含Love 的行,它们会正常打印(带有换行符)。 1 命令是 awk 的神秘简写,用于正常打印。

    【讨论】:

    • 感谢您的解决方案,将来学习 awk 需要一些时间。现在我主要在 sed 上
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-15
    • 2021-03-13
    相关资源
    最近更新 更多