Вставьте несколько строк текста перед конкретной строкой, используя sed
Я пытаюсь вставить несколько строк текста перед конкретной строкой, но продолжаю получать ошибки 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
РЕДАКТИРОВАТЬ!: Извинения, я хотел, чтобы текст был вставлен ДО существующего, а не после!
6 ответов
Это должно работать:
sed -i '/Line to insert after/ i Line one to insert \
second new line to insert \
third new line to insert' file
Для чего-либо, кроме простых замен в отдельных строках, используйте 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
На MacO мне нужно было еще несколько вещей.
- Двойная обратная косая черта после
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
Когда строки для вставки являются результатом некоторой команды "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
Последняя команда может быть легко изменена, если вы хотите вставить ее до совпадения.
Это будет работать с первой строки. Например: если вы хотите вставить из третьей строки файла, замените "1i" на "3i".
sed -i '1i line1'\\n'line2'\\n'line3' 1.txt
cat 1.txt
line1
line2
line3
Hai
Чтобы быть POSIX-совместимым и работать в OS X, я использовал следующее (строка в одинарных кавычках и пустая строка для демонстрационных целей):
sed -i "" "/[pattern]/i\\
line 1\\
line 2\\
\'line 3 with single quotes\`
\\
" <filename>
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
Это можно легко сделать с помощью 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.
$
Это может работать для вас (GNU sed & Bash):
sed -i $'/Line to insert after/a\line1\\nline2\\nline3' file