【问题标题】:using sed to insert file content into a file BEFORE a pattern使用 sed 在模式之前将文件内容插入文件
【发布时间】:2021-02-15 23:34:55
【问题描述】:

我是sed 的新手,我正在尝试将 BFile 的内容插入到文件 AFile 中,在模式之前(在 AFile 中)

以下是我尝试过的:

sed -i '/blah Blah/r BFile' AFile : 在 AFile 的模式之后插入 BFile 的内容。

sed -i '/blah Blah/i BFile' AFile : 它在 AFile 中的模式之前插入 string 'BFile'。

...嗯

我意识到这是因为对正则表达式或 sed 的错误理解:我无法理解 /i/r 在这里的工作原理...我在 sed --help 中找不到任何帮助

有人明白我的意思吗?

问候,

斯坦

【问题讨论】:

  • man sed 阅读手册。

标签: regex sed


【解决方案1】:

这可能对你有用(GNU sed):

sed $'/blah Blah/{e cat BFile\n}' AFile

或:

sed -e 'N;/\n.*blah Blah/{r BFile' -e '};P;D' AFile

或者正如 Alek 指出的那样:

sed '/blah Blah/e cat BFile' AFile

【讨论】:

  • @NeronLeVelu 这是一个 GNU sed 特定命令,请参阅 here
  • 很好的答案,谢谢!为什么不只是sed '/blah Blah/e cat Bfile'
  • 这会将BFile 的内容插入到模式之前的。就我而言,我试图用文件替换模式。这是sed -e '/blah Blah/{r bar' -e 'd}'。值得注意的是 r 命令需要用换行符或单独的 -e ...}src askubuntu.com/a/540538/676225 转义
  • @Alek 我想调用 cat 会降低性能
【解决方案2】:

AFile的内容

one
two
three
blah Blah
four

BFile的内容

...b...

运行这些命令

# get line number
$ sed -n '/blah Blah/=' AFile
4

# read file just before that line
$ sed '3r BFile' AFile
one
two
three
...b...
blah Blah
four

【讨论】:

  • 虽然所有其他 sed 命令都不起作用,如果它是最后一行,则此命令起作用。但是,如果它是第一行,这将不起作用。 :( 我猜你应该使用 or | 链接它,如果它是第一行,则第三次调用 sed。
【解决方案3】:

sed 的 r 命令不会改变模式空间。文件内容在当前循环结束或读取下一个输入行时打印(info sed),因此以下命令中的 N

sed '/blah Blah/ {
r Bfile
N
}' Afile

【讨论】:

  • 如果没有 GNU sed,这个答案会更简单。注意:当/blah Blah/Afile 中的最后一行(带有换行符终止符)时,这不起作用,因为它将追加Bfile 之后,而不是在blah Blah 之前。
【解决方案4】:

只需使用 awk:

在匹配行之前打印 Bfile:

awk 'NR==FNR{bfile = bfile $0 RS; next} /blah Blah/{printf "%s", bfile} {print}' Bfile Afile

在之后打印 Bfile:

awk 'NR==FNR{bfile = bfile $0 RS; next} {print} /blah Blah/{printf "%s", bfile}' Bfile Afile

【讨论】:

    【解决方案5】:
    sed '/blah Blah/ r BFile;x;1!p;${g;p;}' AFile
    

    缓冲当前行,以便在打印当前行之前读取 BFile(实际上是打印下一行)

    【讨论】:

      【解决方案6】:

      [在模式之前将文件内容插入另一个文件]

      sed -i '/PATTERN/r file1' -e //N file2
      

      [模式后]

      sed -i '/PATTERN/r file1' file2
      

      【讨论】:

        【解决方案7】:

        以下是对我有用的解决方案:

        1. 使用像explained in another reply to a similar question这样的标记:

          sed '/blah Blah/i MARKER' AFile | sed -e '/MARKER/r BFile' -e '/MARKER/d'
          
        2. 计数发生时的行like explained in another reply:

          LINE_NUMBER_MATCHING=$(sed -n '/blah Blah/=' AFile) && sed "$((${LINE_NUMBER_MATCHING} - 1))r BFile" AFile
          
        3. 或者使用 sed like explained in another reply:

          sed $'/blah Blah/{e cat BFile\n}' AFile
          

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-06-29
          • 1970-01-01
          • 2018-11-13
          • 2019-03-02
          • 2013-05-24
          • 1970-01-01
          • 2017-02-25
          • 1970-01-01
          相关资源
          最近更新 更多