【问题标题】:sed command to insert multi line string after multi line searchsed 命令在多行搜索后插入多行字符串
【发布时间】:2014-04-26 12:33:53
【问题描述】:

我想在两个特定行之后将文本行插入另一个文本文件。

在类似的东西之后插入

some text...
  example text
    (
    );
some text...

我有一个文本文件(包含两行文本),我希望 sed 将其插入括号之间。

如果我尝试插入的文本文件包含类似于以下内容的内容

need this;
in between the parentheses;

那么我希望结果看起来像这样

some text...
  example text
    (
     need this;
     in between the parentheses;
    );
some text...

最好的解决方案是可以工作的(不必是 sed)。

编辑澄清

在需要插入文本的部分之前还有其他开括号,例如

sometext...
sometext (sometext)....
sometext
  (
  );
  exampletext
    (
    );
sometext...

所以,我认为需要引用“exampletext”然后查找括号。此外,它可能需要准确搜索“exampletext”,因为文档中还有其他行带有“exampletextsometext ...”

完成此操作后,需要将添加到文件中的内容保存在原始文件之上。

【问题讨论】:

  • 您希望文件中只有一对括号吗?他们自己在一条线上吗?他们在线路的起点吗?他们是唯一在线上的东西吗?
  • 不,有多个括号实例。它们需要插入的位置是它们自己所在的位置,如上所示。它们实际上不在行的开头(有制表符或空格将它们与开头分开)。他们是这条线上唯一的角色。它们的独特之处在于示例文本,then (, then );我已经编辑了原始帖子以更好地显示间距的格式。非常感谢您的帮助!

标签: linux bash shell sed command


【解决方案1】:

如果打开的 ( 本身就在一条线上,你可以这样做

sed -e '/^(/r fileToInsert' firstFile

因为/^(/ 找到了您要插入的行(“以左括号开头的行”),而r 表示“读取文件内容并在此时插入。

如果需要确定插入点的表达式必须更复杂,请在 cmets 中详细说明。例如,“完全是一个左括号,没有别的”是/^($/

编辑感谢您澄清要求。如果您需要在example text 之后插入此文本,然后是(,则以下脚本应该可以工作。将其放入自己的文件中,使其可执行 (chmod 755 myScript),然后使用 ./myScript 运行。

#!/bin/bash
sed '
/exampletext/ {
  N
  /(/ r multi2.txt
}' multi1.txt

解释:

/exampletext/ {     find a match of this text, then…
N                   go to the next line
/(/                 match open parenthesis
r multi2.txt        insert file 'multi2.txt' here
}'                  end of script
multi1.txt          name of input file

请注意,这会产生stdout 的输出。你可以把它指向一个新的文件名——例如

./myScript > newFile.txt

我使用以下输入文件 (multi1.txt) 对此进行了测试:

some text...
sometext...
sometext (sometext)....
  exampletext
  not the right string
    (
    );
sometext
  (
  );
  exampletext
    (
    );
sometext...

它给出了输出

some text...
sometext...
sometext (sometext)....
  exampletext
  not the right string
    (
    );
sometext
  (
  );
  exampletext
    (
insert this
and that
    );
sometext...

我认为这是你想要的?文本插入到 example text 后跟一个左括号的位置 - 但不是在中间有另一行时......

【讨论】:

  • Sed 需要区分文档中的其他左括号。需要插入文本的部分的独特质量是“示例文本();”其中示例文本是唯一的,后面有括号。另外,我不确定它是否重要,但行首和 (. 如下所示。' 示例文本 ( ); '
  • @user3439830 - 感谢您的澄清;看看更新后的答案是否适合您?
  • 做到了!非常感谢。这就是我认为它应该看起来的样子,但没有正确构建它。我还在 sed 之后添加了 -i 选项,以便在完成后更新文件。再次感谢!
【解决方案2】:

这是使用awk 的另一种方法:

awk '/^\(/{print $0; while((getline line <"filetoInsert") > 0) print line; next}1' firstFile

说明:

  • 我们使用一个简单的正则表达式/^\(/ 来说明以左括号开头的行。
  • 一旦遇到该行,我们就会打印它。
  • 然后我们使用getline 函数读取第二个文件。
  • 一旦它被完全读取和打印,我们使用next 来避免再次默认打印原始文件行(我们的paren),因为我们已经使用您在末尾看到的1 打开了默认打印。

【讨论】:

  • 我一直想知道如何在awk 中做到这一点(我在sed 之后“更复杂”的文字处理的第二选择) - 你回答了它。我认为在这种情况下sed 解决方案更干净,但我赞成,因为你满足了我的好奇心(在这种情况下证实了我对sed 的偏见)。
  • @Floris 谢谢你的客气话。我完全同意,在某些情况下(例如这个特定的情况)sed 更简洁、更短且更易于理解,您对此表示赞同 :)
  • 我已经修改了我的原始帖子以显示在 ( 之前添加了空格。我已经尝试过这种方法,但它似乎没有产生预期的结果。非常感谢您的帮助!跨度>
  • @user3439830 您可以修改regex 并说/ *\(/ 而不是答案中给出的内容。
  • 此添加将文件插入错误的部分。文档的其他部分有一个开括号。插入文本所属部分的独特之处在于它包含example text,然后在下一行(。这两行也是级联的,如上面新编辑的问题所示。再次感谢!
【解决方案3】:

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

sed -e '$!N;/^(\n);$/{r insert_file' -e '};P;D' first_file

【讨论】:

    【解决方案4】:

    在 python 中也是如此:

    import sys
    
    with open(sys.argv[2]) as secondFile:
        insertStrList=secondFile.readlines()
    
    firstStrList=[]
    with open(sys.argv[1]) as firstFile:
        while True:
            i_str=firstFile.readline()
            if not i_str: 
                break
            firstStrList.append(i_str)
            if i_str == '(\n':
                firstStrList+=insertStrList
    
    print ''.join(firstStrList)
    

    python mergeParenthesis.py a.txt b.txt一起使用

    但我同意弗洛里斯的回答更容易;)

    干杯

    【讨论】:

    • "没有一条 Linux 命令不能变成十几行 Python。"说真的,我是 Python 的忠实粉丝,但我认为在这种情况下它是矫枉过正的。当我处理简单的文本文件时,我会使用sedawk(按此顺序)。在我的书中,Python 是针对“真正的”问题的……您是否尝试过对此进行基准测试?我想知道在较大的文件上,逐行追加操作是否可能不会变得很慢。不确定 Python 的效率如何。你知道吗?
    • 完全同意。我通常使用 awk,我不是 sed 方面的专家。但是我昨天通过你的回答学会了'r'标志。非常感谢。
    猜你喜欢
    • 2013-05-02
    • 2012-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-17
    • 1970-01-01
    • 2014-10-27
    相关资源
    最近更新 更多