Linux sed добавить строку

Insert line after match using sed

For some reason I can’t seem to find a straightforward answer to this and I’m on a bit of a time crunch at the moment. How would I go about inserting a choice line of text after the first line matching a specific string using the sed command. I have .

CLIENTSCRIPT="foo" CLIENTFILE="bar" 
CLIENTSCRIPT="foo" CLIENTSCRIPT2="hello" CLIENTFILE="bar" 

If one needs capture groups to be used in the inserted line, check this question stackoverflow.com/q/39103787/520567

8 Answers 8

Try doing this using GNU sed:

sed '/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"' file 

if you want to substitute in-place, use

sed -i '/CLIENTSCRIPT="foo"/a CLIENTSCRIPT2="hello"' file 

Output

CLIENTSCRIPT="foo" CLIENTSCRIPT2="hello" CLIENTFILE="bar" 

Doc

Note that both assume GNU sed . That’s not standard sed syntax and won’t work with any other sed implementation.

I had trouble getting this to work for me because I was using a different delimiter. After RTFM’ing, I realized I had to start the regex with a \, then the delimiter.

How does it apply ONLY to the first match? it is clear that it append text after the match, but how does it know only to the first match?

Note the standard sed syntax (as in POSIX, so supported by all conforming sed implementations around (GNU, OS/X, BSD, Solaris. )):

sed '/CLIENTSCRIPT=/a\ CLIENTSCRIPT2="hello"' file 
sed -e '/CLIENTSCRIPT=/a\' -e 'CLIENTSCRIPT2="hello"' file 

( -e xpressions (and the contents of -f iles) are joined with newlines to make up the sed script sed interprets).

The -i option for in-place editing is also a GNU extension, some other implementations (like FreeBSD’s) support -i » for that.

Alternatively, for portability, you can use perl instead:

perl -pi -e '$_ .= qq(CLIENTSCRIPT2="hello"\n) if /CLIENTSCRIPT=/' file 

Or you could use ed or ex :

printf '%s\n' /CLIENTSCRIPT=/a 'CLIENTSCRIPT2="hello"' . w q | ex -s file 

I may be wrong, but the current sed -e ‘/CLIENTSCRIPT=/a\’ -e ‘CLIENTSCRIPT2=»hello»‘ file escapes the quote at the end of the first parameter and breaks the command.

Читайте также:  Linux файлы через windows

@AbandonedCart, in shells of the Bourne, csh or rc family, ‘. ‘ are strong quotes inside which backslash is not special. The only exception that I know is the fish shell.

Terminal on MacOS (and subsequently a script run in terminal) is also an exception, apparently. I found alternate syntax, but thanks anyway.

@AbandonedCart, that’s something else. That’s macOS sed not being POSIX compliant here. That makes my statement about it being portable incorrect (for the one line variant). I’ll ask the opengroup for confirmation if it’s indeed a non-conformance or a misinterpretation of the standard on my part.

I had so many problems with different versions of sed that I tried the printf. ex version. This works like charm!

Sed command that works on MacOS (at least, OS 10) and Unix alike (ie. doesn’t require gnu sed like Gilles’ (currently accepted) one does):

sed -e '/CLIENTSCRIPT="foo"/a\'$'\n''CLIENTSCRIPT2="hello"' file 

This works in bash and maybe other shells too that know the $’\n’ evaluation quote style. Everything can be on one line and work in older/POSIX sed commands. If there might be multiple lines matching the CLIENTSCRIPT=»foo» (or your equivalent) and you wish to only add the extra line the first time, you can rework it as follows:

sed -e '/^ *CLIENTSCRIPT="foo"/b ins' -e b -e ':ins' -e 'a\'$'\n''CLIENTSCRIPT2="hello"' -e ': done' -e 'n;b done' file 

(this creates a loop after the line insertion code that just cycles through the rest of the file, never getting back to the first sed command again).

You might notice I added a ‘^ *’ to the matching pattern in case that line shows up in a comment, say, or is indented. Its not 100% perfect but covers some other situations likely to be common. Adjust as required.

Читайте также:  Kali linux apt get не работает

These two solutions also get round the problem (for the generic solution to adding a line) that if your new inserted line contains unescaped backslashes or ampersands they will be interpreted by sed and likely not come out the same, just like the \n is — eg. \0 would be the first line matched. Especially handy if you’re adding a line that comes from a variable where you’d otherwise have to escape everything first using $ before, or another sed statement etc.

This solution is a little less messy in scripts (that quoting and \n is not easy to read though), when you don’t want to put the replacement text for the a command at the start of a line if say, in a function with indented lines. I’ve taken advantage that $’\n’ is evaluated to a newline by the shell, its not in regular ‘\n’ single-quoted values.

Its getting long enough though that I think perl/even awk might win due to being more readable.

Источник

Как добавить строку в начало или в конец каждой строчки

Рассмотрим варианты, когда в командной строке Linux для всех строчек в файле нужно добавить строку в начало, в конец или сразу в начало и конец.

К примеру, нужно добавить в файл .htaccess тысячи IP адресов для блокировки, которые содержатся в текстовом файле, для этого перед ними нужно добавить строку «Require not ip » или «Deny from » (в зависимости от версии сервера, подробнее смотрите «Контроль доступа к сайту (блокировка по IP, User-Agent)»).

Предположим, наш список IP адресов для блокировки содержится в файле hola.ip:

Чтобы добавить перед каждой строкой «Require not ip » достаточно выполнить команду:

sed 's/^/Require not ip /' hola.ip

Это только один из многочисленных примеров, когда на практике может понадобиться добавлять строки до или после текста.

  • ПРЕФИКС — означает текст, вставляемый перед каждой строчкой
  • СУФФИКС — означает текст, вставляемый в конце каждой строчки
    ФАЙЛ.txt — файл, из которого будут считываться строки для изменения
Читайте также:  Linux изменить цвет консоли

Как обычно в Linux, любое действие можно выполнить множеством способов даже с помощью одной команды, поэтому для каждого случая будет показано несколько способов.

Обратите внимание, что начальный файл меняться не будет, а новые значения строк будут выведены в стандартный вывод. Если к любой из последующих команд с sed и perl добавить опцию -i, то изменения будут сделаны в исходном файле вместо вывода результатов в стандартный вывод. Например:

sed -i 's/^/ПРЕФИКС/' hola.ip.bac awk -i '< print "ПРЕФИКС" $0 >' hola.ip.bac

Как добавить строку в начало каждой строчки

С помощью sed (любая из команд):

sed 's/^/ПРЕФИКС/' ФАЙЛ.txt sed -e 's/^\(.*\)$/ПРЕФИКС\1/' ФАЙЛ.txt sed 's/.*/ПРЕФИКС&/' ФАЙЛ.txt

С помощью awk:

С помощью perl (любая из команд):

perl -lne 'print "ПРЕФИКС$_"' ФАЙЛ.txt perl -pe 's/^/ПРЕФИКС/' ФАЙЛ.txt perl -lpe '$_="ПРЕФИКС$_"' ФАЙЛ.txt

Как добавить строку в конец каждой строчки

С помощью sed (любая из команд):

sed 's/$/СУФФИКС/' ФАЙЛ.txt sed -e 's/^\(.*\)$/\1СУФФИКС/' ФАЙЛ.txt sed 's/.*/&СУФФИКС/' ФАЙЛ.txt

С помощью awk:

С помощью perl (любая из команд):

perl -lne 'print "$_СУФФИКС"' ФАЙЛ.txt perl -pe 's/$/СУФФИКС/' ФАЙЛ.txt perl -lpe '$_="$_СУФФИКС"' ФАЙЛ.txt

Как добавить строку в начало и в конец каждой строчки

С помощью sed (любая из команд):

sed 's/^/ПРЕФИКС/; s/$/СУФФИКС/' ФАЙЛ.txt sed -e 's/^\(.*\)$/ПРЕФИКС\1СУФФИКС/' ФАЙЛ.txt sed 's/.*/ПРЕФИКС&СУФФИКС/' ФАЙЛ.txt

С помощью awk:

С помощью perl (любая из команд):

perl -lne 'print "ПРЕФИКС$_СУФФИКС"' ФАЙЛ.txt perl -pe 's/^/ПРЕФИКС/; s/$/СУФФИКС/' ФАЙЛ.txt perl -lpe '$_="ПРЕФИКС$_СУФФИКС"' ФАЙЛ.txt

Связанные статьи:

Источник

Оцените статью
Adblock
detector