【问题标题】:remove newline character after line starting with pattern在以模式开头的行后删除换行符
【发布时间】:2016-06-10 06:05:50
【问题描述】:

我找到了类似问题的解决方案,但并不完全符合我的要求。 基本上,如果第一行以给定的模式开头,我想将两行合并为一个。 从此

One
PATTERN bla bla bla
Three
Four    

到这里

One
PATTERN bla bla bla Three
Four

这种“awk”解决方案不起作用。 Removing new line after a particular text via bash/awk/sed/perl:它将两行打印为一个,但第二行在开头并部分覆盖了第一行。

编辑:所有这些解决方案都有相同的结果。为了更清楚,我会放原文。 原线

LOCUS       NODE_10_length_218773_cov_81.1626_ID_>218773 bp   DNA linear
BCT09-MAY-2016

sed 和 awk 处理都返回

 BCT09-MAY-2016E_10_length_218773_cov_81.1626_ID_>218773 bp   DNA linear

但是如果我将标准输出重定向到一个文件,我们似乎就快到了

LOCUS       NODE_10_length_218773_cov_81.1626_ID_>218773 bp   DNA linear^M BCT09

但是 ^M 是从哪里来的呢?

【问题讨论】:

  • 这些解决方案不起作用在这里没有多大用处。但是向我们展示您如何修改这些解决方案以适应您的问题是很有用的。
  • 我怀疑你的源文件是在 Windows 上生成的,其中行尾包含在 CR+LF 中,而在 Linux 上这只是 LF。解决方案是无条件删除\r chars。
  • 你说得对,我之前没有遇到过这个问题。删除 \r 后一切正常,因此它可能算作重复问题

标签: bash awk


【解决方案1】:

您可以使用ORS 输出记录分隔符非常轻松地做到这一点

awk '$1 !~ /PATTERN/{ORS="\n"} $1 ~ /PATTERN/{ORS=" "} 1'

示例

$ awk '$1 !~ /PATTERN/{ORS="\n"} $1 ~ /PATTERN/{ORS=" "} 1' input
One
PATTERN bla bla bla Three
Four

或者更简单地说,

awk 'ORS = $1 ~ /PATTERN/ ? " " : "\n"'

示例

$ awk 'ORS = $1 ~ /PATTERN/ ? " " : "\n"' input
One
PATTERN bla bla bla Three
Four

它有什么作用?

  • ORS = $1 ~ /PATTERN/ ? " " : "\n" 根据模式匹配将ORS 设置为空格或换行符。

    现在表达式总是计算为真,在这种情况下awk 将打印整个输入记录。

【讨论】:

  • 谢谢,尤其是总是有用的解释。仍然由于某种原因它几乎可以工作(见主帖中的编辑)
【解决方案2】:
sed -e '/^PATTERN/{N; s/\n/ /;}'

【讨论】:

  • 刚刚注意到您链接到的问题中给出了这个解决方案......您需要澄清那里给出的解决方案有什么问题,因为它们似乎回答了您的问题。
  • 老实说,我没有注意到那个解决方案,所以感谢您指出这一点。无论如何,我刚刚尝试并意识到所有这些解决方案都有一个共同的问题,我将在第一篇文章中写下。
【解决方案3】:

假设你有 gnu-awk 下面的解决方案:

awk 'BEGIN{RS="^$"}{$0=gensub(/bla\nThree/,"bla Three","g",$0);print}' your_file

应该这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-15
    • 2021-01-08
    • 1970-01-01
    • 1970-01-01
    • 2014-05-27
    • 1970-01-01
    相关资源
    最近更新 更多