Вставьте несколько строк текста перед определенной строкой, используя Bash

Я пытаюсь вставить несколько строк текста перед определенной строкой, но продолжаю получать ошибки 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

Сообщается об ошибке:

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

Я пробовал, используя \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

РЕДАКТИРОВАТЬ!: Извините, я хотел, чтобы текст был вставлен ПЕРЕД существующим, а не после!


person MeanwhileInHell    schedule 14.08.2015    source источник


Ответы (9)


Это должно работать:

sed -i '/Line to insert after/ i Line one to insert \
second new line to insert \
third new line to insert' file
person anubhava    schedule 14.08.2015
comment
Возможно, вы захотите использовать a, если вы вставляете после - person 123; 14.08.2015
comment
Превосходный гид. Большое спасибо @anubhava - person Chaminda Bandara; 16.05.2017
comment
Есть ли способ вставить в наш файл несколько строк, написанных в отдельном файле? Предложение типа этого . - person aquaman; 10.03.2018

Для всего, кроме простых замен в отдельных строках, используйте awk вместо sed для простоты, ясности, надежности и т. д. и т. д.

Чтобы вставить перед строкой:

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

Чтобы вставить после строки:

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
person Ed Morton    schedule 14.08.2015

Когда строки, которые нужно вставить, являются результатом некоторой команды «mycmd» (например, cat results.txt или printf "%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

Последнюю команду можно просто изменить, если вы хотите вставить перед некоторым совпадением.

person Walter A    schedule 02.01.2019

На MacOs мне нужно было еще несколько вещей.

  • Двойная обратная косая черта после i
  • Пустые кавычки после -i, чтобы указать отсутствие файла резервной копии
  • Начальная обратная косая черта для добавления ведущего пробела
  • Двойная обратная косая черта в конце для добавления новых строк

Этот код ищет первый экземпляр </plugins в pom.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
person Mark    schedule 28.05.2019
comment
Люблю этот краткий ответ. Спасибо. - person kakyo; 14.07.2020

Это может сработать для вас (GNU sed и Bash):

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

Это работает с первой строки. Например: если вы хотите вставить с 3-й строки файла, замените «1i» на «3i».

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

cat 1.txt

 line1
 line2
 line3
 Hai
person vishnu raja    schedule 22.09.2017

Чтобы быть совместимым с POSIX и работать в OS X, я использовал следующее (строка с одинарными кавычками и пустая строка предназначены для демонстрационных целей):

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

Это также легко сделать с помощью 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.
$
person stack0114106    schedule 03.01.2019

person    schedule
comment
Возможно, вам следует объяснить, что делает ваше изменение. - person drescherjm; 14.08.2015