使用 Bash 在特定行之前插入多行文本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32007152/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 13:25:44  来源:igfitidea点击:

Insert multiple lines of text before specific line using Bash

bashunixsedtext-manipulation

提问by MeanwhileInHell

I am trying to insert a few lines of text before a specific line, but keep getting sed errors when I try to add a new line character. My command looks like:

我试图在特定行之前插入几行文本,但是当我尝试添加新行字符时不断收到 sed 错误。我的命令看起来像:

sed -r -i '/Line to insert after/ i Line one to insert \
    second new line to insert \
    third new line to insert' /etc/directory/somefile.txt

The error that is reported is:

报告的错误是:

sed: -e expression #1, char 77: unterminated `s' command

I've tried, using \n, \\(as in the example), no character at all, just moving the second line to the next line. I've also tried something like:

我试过,使用\n, \\(如示例中所示),根本没有字符,只是将第二行移到下一行。我也试过类似的东西:

sed -r -i -e '/Line to insert after/ i Line one to insert'
    -e 'second new line to insert'
    -e 'third new line to insert' /etc/directory/somefile.txt

EDIT!: Apologies, I wanted the text inserted BEFORE the existing, not after!

编辑!:抱歉,我希望在现有文本之前而不是之后插入文本!

回答by anubhava

This should work:

这应该有效:

sed -i '/Line to insert after/ i Line one to insert \
second new line to insert \
third new line to insert' file

回答by Ed Morton

For anything other than simple substitutions on individual lines, use awk instead of sed for simplicity, clarity, robustness, etc., etc.

对于除个别行上的简单替换之外的任何其他内容,为了简单、清晰、健壮等,请使用 awk 而不是 sed。

To insert before a line:

在一行前插入:

awk '
/Line to insert before/ {
    print "Line one to insert"
    print "second new line to insert"
    print "third new line to insert"
}
{ print }
' /etc/directory/somefile.txt

To insert after a line:

在一行后插入:

awk '
{ print }
/Line to insert after/ {
    print "Line one to insert"
    print "second new line to insert"
    print "third new line to insert"
}
' /etc/directory/somefile.txt

回答by Walter A

When the lines to be inserted are the result of some command "mycmd" (like cat results.txtor printf "%s\n" line{1..3}), you can do

当要插入的行是某些命令“mycmd”(如cat results.txtprintf "%s\n" line{1..3})的结果时,您可以执行

sed -i 's/Line to insert after/r' <(cmd) file
or 
sed -i 's/Line to insert after/echo "&";cmd/e' file

The last command can be simple modified when you want to insert beforesome match.

当您想某些匹配之前插入时,可以简单地修改最后一个命令。

回答by stack0114106

This can be easily done with Perl also

这也可以用 Perl 轻松完成

$ cat MeanwhileInHell.txt
Iran|XXXXXX|Iranian
Iraq|YYYYYY|Iraquian
Saudi|ZZZZZ|Saudi is a Rich Country
USA|AAAAAA|USA is United States of America.
India|IIII|India got freedom from British.
Scot|SSSSS|Canada Mexio.
$ perl -pe 'BEGIN {$x="Line one to insert\nLine 2\nLine3\n"} $_=$x.$_ if /USA/ ' MeanwhileInHell.txt
Iran|XXXXXX|Iranian
Iraq|YYYYYY|Iraquian
Saudi|ZZZZZ|Saudi is a Rich Country
Line one to insert
Line 2
Line3
USA|AAAAAA|USA is United States of America.
India|IIII|India got freedom from British.
Scot|SSSSS|Canada Mexio.
$

回答by Mark

On MacOs I needed a few more things.

在 MacO 上,我还需要一些东西。

  • Double backslash after the i
  • Empty quotes after the -ito specify no backup file
  • Leading backslashes to add leading whitespace
  • Trailing double backslashes to add newlines
  • 后面的双反斜杠 i
  • 后面的空引号-i指定没有备份文件
  • 前导反斜杠以添加前导空格
  • 尾随双反斜杠以添加换行符

This code searches for the first instance of </pluginsin pom.xml and inserts another XML object immediately preceding it, separated by a newline character.

此代码搜索</pluginspom.xml 中的第一个实例,并在它之前插入另一个 XML 对象,用换行符分隔。

sed -i '' "/\<\/plugins/ i \
\            <plugin>\
\                <groupId>org.apache.maven.plugins</groupId>\
\                <artifactId>maven-source-plugin</artifactId>\
\                <executions>\
\                    <execution>\
\                        <id>attach-sources</id>\
\                        <goals>\
\                            <goal>jar</goal>\
\                        </goals>\
\                    </execution>\
\                </executions>\
\            </plugin>\
" pom.xml

回答by vishnu raja

This ll works from the first line.. For eg: If you want to insert from 3rd line of a file, replace "1i" to "3i".

这将从第一行开始。例如:如果您想从文件的第三行插入,请将“1i”替换为“3i”。

sed -i '1i line1'\n'line2'\n'line3' 1.txt 

cat 1.txt

 line1
 line2
 line3
 Hai

回答by Andi

To be POSIX compliant and run in OS X, I used the following (single quoted line and empty line are for demonstration purposes):

为了兼容 POSIX 并在 OS X 中运行,我使用了以下内容(单引号和空行用于演示目的):

sed -i "" "/[pattern]/i\
line 1\
line 2\
\'line 3 with single quotes\`
\
" <filename>

回答by Mahesh Kharvi

sed -i '/Line to insert after/ i\
Line one to insert\
second new line to insert\
third new line to insert' /etc/directory/somefile.txt

回答by potong

This might work for you (GNU sed & Bash):

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

sed -i $'/Line to insert after/a\line1\nline2\nline3' file