【问题标题】:Print all lines but concatenate consecutive lines matching a pattern打印所有行,但连接匹配模式的连续行
【发布时间】:2020-06-16 21:47:55
【问题描述】:

我有一个包含以下数据的文件:

;Citation1 begins here and contains characters including , . and numbers

DATA 1 259.85 101000 0.094837707 0.9089 / 
         2 266.07 101000 0.097842938 0.8997 / 
         3 270.95 101000 0.105071894 0.8899 / 
         4 273.35 101000 0.112016587 0.8849 / 
         5 278.75 101000 0.134569045 0.87 / 

;Citation2 begins here and contains characters including , . and numbers but
;this one continues on the next line

DATA 1 259.85 101000 0.094837707 0.9089 / 
         2 266.07 101000 0.097842938 0.8997 / 
         3 270.95 101000 0.105071894 0.8899 / 
         4 273.35 101000 0.112016587 0.8849 / 
         5 278.75 101000 0.134569045 0.87 / 

我想将所有行打印到一个新文件中。但是,当连续的行以相同的字符(此处为“;”)开头时,我想将它们连接到同一行。因此,上述输入文件将显示为:

;Citation1 begins here and contains characters including , . and numbers

DATA 1 259.85 101000 0.094837707 0.9089 / 
         2 266.07 101000 0.097842938 0.8997 / 
         3 270.95 101000 0.105071894 0.8899 / 
         4 273.35 101000 0.112016587 0.8849 / 
         5 278.75 101000 0.134569045 0.87 / 

;Citation2 begins here and contains characters including , . and numbers but this one continues on the next line

DATA 1 259.85 101000 0.094837707 0.9089 / 
         2 266.07 101000 0.097842938 0.8997 / 
         3 270.95 101000 0.105071894 0.8899 / 
         4 273.35 101000 0.112016587 0.8849 / 
         5 278.75 101000 0.134569045 0.87 / 

我尝试过使用不同的 awk 命令变体,例如:

awk '/;/ && last {printf "%s","\n"last;$0}{printf "%s",$0}END{print} /;/{last=$0}' input.txt > output.txt

但没有成功。

【问题讨论】:

  • 欢迎来到 SO,在 SO 上,我们鼓励用户添加他们为解决自己的问题而付出的努力,所以请添加相同的内容并让我们知道。
  • 为什么不专注于三个规则?第一个查找/^;/(连接所有行,从字符2 开始,递增计数器n 跳到下一条记录)下一个检查是否n > 0(打印以';' 为前缀并附加'\n' 的连接行,重置您的字符串和计数器,跳到下一个)和最终规则1(默认打印)。试一试,通过提供 A Minimal, Complete, and Verifiable Example (MCVE) 告诉我们您遇到的问题。
  • 我编辑了帖子以解决第一条评论。我尝试了那条线的一百万种变体,但没有运气。通过第二条评论,我理解了逻辑,但我仍在尝试找出正确的语法来实现它。谢谢!
  • @user13758913 干得好。您会看到我会在 Ed 的答案下方发布的内容(在完美的 awk 解决方案上很难与 Ed 竞争)。访问 cmets 中提供的链接 Ed 以调查和纠正您在数据文件中遇到的任何杂散行结束问题。两种解决方案都可以使用从您的问题中复制和粘贴的输入来满足您的要求。

标签: awk concatenation match


【解决方案1】:
$ awk '
    {
        curr = $0
        printf "%s%s", ( (prev ~ /^;/) && sub(/^;/,"") ? OFS : ors ), $0
        ors = ORS
        prev = curr
    }
    END { print "" }
' file
;Citation1 begins here and contains characters including , . and numbers

DATA 1 259.85 101000 0.094837707 0.9089 /
         2 266.07 101000 0.097842938 0.8997 /
         3 270.95 101000 0.105071894 0.8899 /
         4 273.35 101000 0.112016587 0.8849 /
         5 278.75 101000 0.134569045 0.87 /

;Citation2 begins here and contains characters including , . and numbers but this one continues on the next line

DATA 1 259.85 101000 0.094837707 0.9089 /
         2 266.07 101000 0.097842938 0.8997 /
         3 270.95 101000 0.105071894 0.8899 /
         4 273.35 101000 0.112016587 0.8849 /
         5 278.75 101000 0.134569045 0.87 /

【讨论】:

  • 好的,这比awk '/^;/ {s=substr($0,2);cite=(n>0)?cite" "s:s; n++; next}; n>0 {print ";"cite; cite=""; n=0; next}1' file更酷了
  • 谢谢!两者都工作得很好。但是,有没有办法连接第二行文本,使其显示在前一行。现在,它们仍然出现在两个单独的行中,但第二行缺少它的 ';'
  • 正如您在我的回答中看到的那样,这并没有发生,它完全符合您的要求。如果您得到不同的结果,那么您要么错误地复制/粘贴了我的脚本,要么您的实际输入与您发布的示例不同。
  • 我相信你所说的第二种可能性是正在发生的事情。我认为我的输入文件在第一引文行的末尾有一些东西。我不确定它可能是什么,因为它看起来就像一个换行符。无论如何,我会尝试解决它。感谢您的帮助
  • 不客气。应该是CR。请参阅https://stackoverflow.com/questions/45772525/why-does-my-tool-output-overwrite-itself-and-how-do-i-fix-it 了解相关信息,并参阅stackoverflow.com/help/someone-answers 了解该问题下一步要做什么。
猜你喜欢
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
  • 2017-05-27
  • 2022-01-13
  • 1970-01-01
  • 2019-04-29
  • 2018-09-06
相关资源
最近更新 更多