【问题标题】:Sed combine only certain lines within directorySed 仅组合目录中的某些行
【发布时间】:2016-12-25 10:00:02
【问题描述】:

我正在使用 sed 来组合目录中的文本文件行。 命令 cd dir && sed -e 'N;s/\n//' *.txt 可以很好地做到这一点,但是有什么办法可以调整它以仅将以 ** 开头的行句子与以下句子结尾结合起来在 **。所以

This is Line1    
**This is Line2    
This is Line3**    
This is Line4    
This is Line5 

变成

This is Line1    
** This is Line2 This is Line3**    
This is Line4    
This is Line5 

【问题讨论】:

  • Line2 和 Line3 之间是否有空行,或者只是显示示例中的格式问题?
  • 没有空行只是格式。
  • 问题是匹配特殊的 2 行文本还是特定的行号?祝你好运。
  • 只是为了匹配特殊的 2 行文本,我意识到在文件中段落之间有一些空格,但特殊的两行之间没有空行,如果这有区别的话
  • 那么,没有任何答案对您有用吗?

标签: sed


【解决方案1】:

sed 用于在单独的行上进行简单的替换,仅此而已。对于其他任何事情,您都应该使用 awk。这将完成您在示例输入/输出中显示的内容:

$ awk '{ORS=(/^\*\*/?FS:RS)}1' file
This is Line1
**This is Line2 This is Line3**
This is Line4
This is Line5

但当然它不能解决您尚未与我们分享的任何要求(例如,当一行以 ** 开头但下一行不以 ** 结尾时该怎么办,反之亦然或以 ** 开头和结尾的行或以 ** 开头的行位于输入文件的末尾或....)。

【讨论】:

  • 这个效果更好,谢谢你是否可以缩小“This is Line2 This is Line3”之间的差距,使其成为一个坚实的句子?
  • 当然,将FS 更改为"",但如果这是您想要的,那么为什么在您的问题中显示一个空白作为所需的输出?
  • 我很抱歉没有意识到我在上面这样做了。
  • 我更深入地研究了 awk,为什么当我尝试使用上面的命令将更改保存到实际文件而不是使用 >> 重定向到 stdout 时,它会继续提示我输入?
  • 您在问为什么command file >> file(在这种情况下command 是awk 但可能是任何命令)不起作用?你希望它能做什么?如果您希望将命令的输出写入您用作输入的文件,那就是command file > tmp && mv tmp file。如果您尝试写入您正在读取的同一个文件,shell 可以为所欲为,包括在命令从中读取第一行之前清空文件。一些工具(例如 perl、GNU sed、GNU awk)可以选择“就地编辑”,但它们实际上也只是在内部使用 tmp 文件。
【解决方案2】:

Sed 是你的朋友

$ sed '/^\*\*/{:l1;/\*\*$/!{N;bl1};s/\n/ /g;}' file
This is Line1

**This is Line2  This is Line3**

This is Line4

This is Line5

【讨论】:

    【解决方案3】:

    你可以使用这个sed:

    sed '/^\*\*/{:loop; N; /\*\*$/{s/\n/ /g;p;d;}; b loop}' file
    

    测试:

    $ cat file
    This is Line1
    **This is Line2
    in between
    This is Line3**
    This is Line4
    **This is Line5
    This is Line6**
    
    $ sed '/^\*\*/{:loop; N; /\*\*$/{s/\n/ /g;p;d;}; b loop;}' file
    This is Line1
    **This is Line2 in between This is Line3**
    This is Line4
    **This is Line5 This is Line6**
    

    【讨论】:

    • 运行命令时出现错误代码 1“意外的 EOF(待处理的 })。
    • 有空行需要保持原样?
    • @NickJ,更新答案。
    • @sjsam,OP说没有空行。这只是格式化。
    • 我不得不更正我的陈述,文档中的段落之间有空行。
    【解决方案4】:
    $ cat ip.txt
    This is Line1
    **This is Line2
    This is Line3**
    This is Line4
    This is Line5 
    
    $ # this slurps entire file
    $ perl -0777 -pe 's/^(\*\*.*)\n(.*\*\*)$/$1 $2/mg' ip.txt 
    This is Line1
    **This is Line2 This is Line3**
    This is Line4
    This is Line5 
    
    $ # can use this if testing start of line for ** is enough
    $ perl -pe 's/\n/ / if /^\Q**/' ip.txt
    

    参考:How do I search and replace across multiple lines with Perl?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-09
      • 1970-01-01
      • 2021-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多