【问题标题】:How to insert string or newline before a pattern "Using SED" ( Without replacing the pattern) In MAC OS如何在 MAC OS 中的模式“使用 SED”(不替换模式)之前插入字符串或换行符
【发布时间】:2013-11-04 13:54:15
【问题描述】:

我有一个包含以下内容的文件:

aaaabbaaabbaa

我需要这样的输出:

aaaa
bbaaa
bbaa

我需要在第一次出现'b' 之前添加一个新行。我只需要在 bash 中使用 SED 命令

我正在使用以下命令。我知道它现在是完美的..

谁能告诉我比这更好的命令。 请注意我需要在 bash 中使用的 SED 命令

sed -i.bak  -e 's/bb/qbb/g' input.txt  
sed -i.bak  -e 's/qbb/\'$'\nbb/g' input.txt

【问题讨论】:

  • 跳过q中介,直接使用's/b/\'$'\n'bb/g
  • 最短的:11 字符:s/b+/\n&/g + r 开关:sed -re 's/b+/\n&/g' 将完成这项工作。

标签: bash macos shell sed


【解决方案1】:

sed:

$ echo "aaaabbaaabbaa" | sed -r 's/([b]+)/\n\1/g'
aaaa
bbaaa
bbaa

sed -r 允许使用() 捕获块并使用\1 将它们打印回来。它捕获它的块[b]+,意思是"one or more b's",并在新行之前将其打印回来。

我看到你正在使用sed -i,这样做也很好:

sed -i.bak -r 's/([b]+)/\n\1/g' input.txt

而且,更简单 (thanks Glenn Jackman!)

$ echo "aaaabbaaabbaa" | sed 's/b\+/\n&/g'
aaaa
bbaaa
bbaa

它替换“b”的所有序列,并用一个换行符替换它,后跟相同的“b”序列(& 表示在 s/// 左侧匹配的任何内容)。

【讨论】:

  • 不需要-rsed 's/b\+/\n&/g'
  • 嗯,所以这是个好消息:当只捕获一个块时,我们可以使用&,无需\1。我喜欢,谢谢!也更新了。
  • 由于&1,输出中bb之后出现了额外的1
  • 哎呀,我在做一些测试,忘了删除它:) 谢谢@anubhava!
  • @sam 就像你在 Mac OS 上一样,我没有它要测试,你最好检查一下其他答案。
【解决方案2】:

grep -oP 使用前瞻正则表达式会更容易:

echo 'aaaabbaaabbaa' | grep -oP '.+?[^b](?=(b|$))'

aaaa
bbaaa
bbaa

【讨论】:

  • greps 和 -P 很好,但 OSX 在 10.8 中取消了它。
  • 所以你的 grepv 不支持 grep -P ?
【解决方案3】:

如果您的输入字符串确实只包含ab 字符,那么我认为问题会退化为简单地将ab 的所有实例替换为a<newline>b。如果是这种情况,那么您可以完全省略 sed 并使用 Shell Parameter Expansion feature in bash

在终点站:

$ str="aaaabbaaabbaa"
$ echo "${str//ab/a
> b}"
aaaa
bbaaa
bbaa
$ 

或者在 shell 脚本中:

$ cat ab.sh 
#!/bin/bash
echo "${1//ab/a
b}"
$ ./ab.sh "aaaabbaaabbaa"
aaaa
bbaaa
bbaa
$ 

这适用于我在 OSX 10.8.5 上。

此信息也可通过 apple.com 托管的bash manpage 获得。在该页面上搜索“参数/模式”。

【讨论】:

    【解决方案4】:
    echo "aaaabbaaabbaa\nbbaabba" | sed 's/\([^b]\)b/\1\
    b/g'
    
    aaaa
    bbaaa
    bbaa
    bbaa
    bba
    

    posix 兼容,如果行以 b 开头,则不会换行

    【讨论】:

      【解决方案5】:

      这可能对你有用:

      sed -e :a -e '/ab\(.*\)\(.\)$/!b' -e G -e 's//a\2b\1/' -e ta file
      

      这循环遍历当前行,将任何ab 组合替换为a\nb。它使用保持空间的副作用,即在创建新的 sed 实例时始终存在换行符。

      当然:

      sed 's/bb*/\n&/g' file
      

      或:

      sed 's/bb*/'"\n"'&/g' file
      

      要容易得多,但可能取决于 GNU 版本的 sed 或 bash。

      【讨论】:

        【解决方案6】:

        sed -e 's/bb/\ nn/g' 输入.txt

        我得到了这个工作。这与您最初的尝试非常相似。我使用的是 iMac,所以我很确定这对你也有用。

        【讨论】:

          【解决方案7】:

          b 出现在行首并且所有这些都符合 POSIX 标准时,您希望避免换行。

          $ echo -e "aaaabbaaabbaa\nbbaaaabbaaabbaa" | sed -e 's/\([^b]\)b/\1\nb/g'
          aaaa
          bbaaa
          bbaa
          bbaaaa
          bbaaa
          bbaa
          

          【讨论】:

          • 它在终端中工作正常......但是当我将它插入我的 bash 脚本时它不起作用......
          • @sam:听起来很奇怪。您的终端正在运行 shell。您在终端中输入的内容(应该)与 shell 脚本中的行完全相同。如果没有,那是真的坏了。
          【解决方案8】:

          一个丑陋的awk 版本:)

          echo "aaaabbaaabbaa" | awk '{for (i=1;i<=NF;i++) {printf ($i=="b" && f!="b" ?"\n":"")"%s",$i; f=$i}} END {print ""}' FS=
          aaaa
          bbaaa
          bbaa
          

          gnu awk 版本

          echo "aaaabbaaabbaa" | awk '{$1=$1} NR>1 {$0=RS $0;} 1' RS="bb"
          aaaa
          bbaaa
          bbaa
          

          另一个awk。将任何bb 组替换为换行符及其本身&amp;

          echo "aaaabbaaabbaa" | awk 'gsub(/b+/,"\n&")'
          aaaa
          bbaaa
          bbaa
          

          【讨论】:

          • 我明白了。但是如果awk 已安装(正常安装)并且做得更好,您可能会为您提供更好的工具。
          • 我不希望用户为我安装 awk。这就是为什么没有 AWK
          • 添加了另一个awk 版本。你在哪个系统上没有awk
          【解决方案9】:

          你可以说:

          $ echo aaaabbaaabbaa | sed 's/b\{1,\}/\'$'\n&/g'
          aaaa
          bbaaa
          bbaa
          

          $ echo aaaabbaaabbaa | sed $'s/b\{1,\}/\\\n&/g'
          aaaa
          bbaaa
          bbaa
          

          为了使sed 将正则表达式解释为扩展正则表达式,您可以使用-E 选项:

          $ echo aaaabbaaabbaa | sed -E 's/b+/\'$'\n&/g'
          aaaa
          bbaaa
          bbaa
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-08-21
            • 2014-03-18
            • 2017-12-17
            • 2023-02-04
            • 2019-03-28
            • 2011-05-29
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多