Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux sed仅在第一次匹配时插入_Linux_Bash_Sed - Fatal编程技术网

Linux sed仅在第一次匹配时插入

Linux sed仅在第一次匹配时插入,linux,bash,sed,Linux,Bash,Sed,更新: 使用sed,如何仅在每个文件的第一个匹配关键字上插入(而不是替换)新行 目前,我有以下内容,但这将为包含匹配关键字的每一行插入,并且我希望它仅为文件中找到的第一个匹配项插入新插入的行: sed -ie '/Matched Keyword/ i\New Inserted Line' *.* 例如: Myfile.txt: Line 1 Line 2 Line 3 This line contains the Matched Keyword and other stuff Line 4 T

更新:

使用sed,如何仅在每个文件的第一个匹配关键字上插入(而不是替换)新行

目前,我有以下内容,但这将为包含匹配关键字的每一行插入,并且我希望它仅为文件中找到的第一个匹配项插入新插入的行:

sed -ie '/Matched Keyword/ i\New Inserted Line' *.*
例如:

Myfile.txt:

Line 1
Line 2
Line 3
This line contains the Matched Keyword and other stuff
Line 4
This line contains the Matched Keyword and other stuff
Line 6
改为:

Line 1
Line 2
Line 3
New Inserted Line
This line contains the Matched Keyword and other stuff
Line 4
This line contains the Matched Keyword and other stuff
Line 6

如果您想要一个带sed*:

sed '0,/Matched Keyword/s//Matched Keyword\nNew Inserted Line/' myfile.txt

*仅适用于GNU sed

您可以在GNU sed中执行以下操作:

sed '0,/Matched Keyword/s//New Inserted Line\n&/'
但它不是便携式的。因为可移植性很好,所以在awk中:

awk '/Matched Keyword/ && !x {print "Text line to insert"; x=1} 1' inputFile
或者,如果要传递变量以进行打印:

awk -v "var=$var" '/Matched Keyword/ && !x {print var; x=1} 1' inputFile
根据您的示例,这两个选项都在关键字第一次出现之前插入文本行,并单独插入一行

记住,对于sed和awk,匹配的关键字是正则表达式,而不仅仅是关键字

更新:

因为这个问题也被标记了,所以这里有一个简单的解决方案,它是纯bash的,不需要sed:

#!/bin/bash

n=0
while read line; do
  if [[ "$line" =~ 'Matched Keyword' && $n = 0 ]]; then
    echo "New Inserted Line"
    n=1
  fi
  echo "$line"
done

就目前而言,这就像一根管子。您可以轻松地将其包装为对文件起作用的内容。

这可能适合您:

sed -i -e '/Matched Keyword/{i\New Inserted Line' -e ':a;n;ba}' file
你快到了!只需创建一个循环,从
匹配的关键字
读取到文件末尾

插入一行后,可以通过以下方式打印文件的其余部分:

  • 引入循环占位符
    :a
    (此处
    a
    为任意名称)
  • 打印当前行,并使用
    n
    命令将下一行提取到图案空间中
  • 使用
    ba
    命令将控制重定向回
    a
    占位符,该命令本质上是一个
    goto
    。文件结束条件自然由
    n
    命令处理,如果试图读取文件结束,该命令将终止任何其他sed命令
  • 在bash的帮助下,可以实现真正的一行程序:

    sed $'/Matched Keyword/{iNew Inserted Line\n:a;n;ba}' file
    
    备选方案:

    sed 'x;/./{x;b};x;/Matched Keyword/h;//iNew Inserted Line' file
    

    这将使用
    Matched关键字
    作为保留空间中的一个标志,一旦设置了它,任何处理都会通过立即退出来缩减。

    如果您只想在第一次匹配后追加一行,请使用AWK而不是下面的SED

    awk '{print} /Matched Keyword/ && !n {print "New Inserted Line"; n++}' myfile.txt
    
    输出:

    Line 1
    Line 2
    Line 3
    This line contains the Matched Keyword and other stuff
    New Inserted Line
    Line 4
    This line contains the Matched Keyword and other stuff
    Line 6
    

    可能的重复-您可以通过使用换行符和反向引用来调整它。这也回答了你的问题吗?这对我一点用都没有。啊,你的解决方案显然是针对GNU的。虽然它仍然是错误的,但是,唉,它在GNU-sed版本4.2.1中对我有效@Squazic,也许你想限定你的答案。祝大家好运,这对我很有效。我只是将匹配的关键字与新插入的行交换,因为我希望插入发生在匹配的关键字之前。感谢大家的投入。在传统的sed中没有办法做到这一点吗?也许可以将Poton的解决方案用于非GNU sed。但它不会是一个班轮。我通常只做一句话。:-)@Velthune-一点也不,这是一个很好的补充。谢谢。:)嗯,是的,你能给出一个完全有效的例子吗?因为我不知道如何在sed单行表达式中创建这个“循环”。你是如何做到的?