Linux sed добавление строки

Примеры команды sed для работы со строками файлов

Sed умеет очень круто обрабатывать файлы. Давайте рассмотрим несколько примеров. Например, нужно вставить новую строку в файл после определённой линии:

sed '3 a new line content' my.txt

Данная команда добавит новую строку в файл my.txt с содержимым new line content усразу после текущей третей строки в файле.

Чтобы добавить строку в конец вместо её номера нужно указать символ $:

sed '$ a new line content' my.txt

Усложняем задачу. Нужно вставить линию не после определённого номера строки, а после строки с определённым содержанием:

sed '/PATTERN/ a new line content' my.txt

А что если нужно новую линию вставить не после, а до? Тогда вместо параметра a нужно указать параметр i:

sed ‘3 i new line content’ my.txt

sed ‘$ i new line content’ my.txt

sed ‘/PATTERN/ i new line content’ my.txt

Читайте также

Про тимлида и его команды Не для всех очевидно, что тимлид/PM/CTO работает одновременно в двух командах и с каждой из них ему следует выстраивать свои…

Отслеживание измененных файлов Отслеживаем измененные файлы и отправляем отчет на эмейл. 00 00 * * * find /path/to/folder -mtime -1 -type f | mailx -s «Subj» my@email.here

Какие команды терминала вы используете чаще всего? Многие из нас используют командную строку на регулярной основе. А вы когда-нибудь задавались вопросом, какие команды вы используете чаще всего?…

Источник

Append text to file using sed

How can I write text to a file using sed? More specifically I would it add null variables to my blank text file that was created using touch. The syntax of sed is very confusing to me.

Please show us what you’ve tried, along with your results, and an example of the output you’re expecting.

4 Answers 4

sed -i "$ a some text" somefile.txt 

It’s useful to know how to actually do this with sed. Sometimes you want to use sed to make multiple changes to a file, including adding a line to the end, and it’s nice to be able to do that in a single command.

specially useful since it can be used with sudo , while sudo echo > file would be doing a sudo echo and then redirecting the output as non-sudo to file

This is a syntax error on MacOS and other *BSD platforms. The a command is not properly standardized by POSIX so whether or not it works on an empty file is probably platform-dependent. The syntactically correct sed -i » ‘a$\ (newline) some text’ somefile.txt does not actually modify an empty file on MacOS Big Sur, like @doak already remarked (presumably regarding Linux).

Читайте также:  Alt linux настройка samba

This adds the text on a new line, what if I want to append it inline? Do I really have to use s/$/. / ?

If you’re just appending text to the end of the file then you wouldn’t use sed in the first place.

echo "some text" >> somefile.txt 

I’ve been using an example to change variables in a file, I thought maybe you could add them too. This is MUCH simpler.

Adding a late post because while the accepted answer is the simplest solution to this problem, the question actually highlights a couple of common situations:

In short, you can’t touch , then edit a file with sed . Sed doesn’t work on empty files, but occasionally you need to do the equivalent of

sudo echo "some text" >> somefile.txt 

sudo doesn’t like the redirect, but there are workarounds:

echo "some text" | sudo tee --append somefile.txt 

or if pipes are not an option either, or you simply must use sed, or you just like complexity:

dd if=/dev/zero count=1 bs=1 of=somefile.txt sed -i '$ a some text' somefile.txt sed -i '1 d' somefile 

On some systems,. you might have to use sed -i -e ‘$ a .

This sounds like an XY Problem to me. You might get better or more useful answers if you ask about what problem you’re trying to solve, rather than asking for help implementing a particular solution.

But if you absolutely must do this in sed, you can use sed’s r command to read a file. For example:

[ghoti@pc ~/tmp]$ cat one RED BLUE [ghoti@pc ~/tmp]$ cat two green yellow [ghoti@pc ~/tmp]$ echo ">> start"; sed '$r two' one; echo ">> end" >> start RED BLUE green yellow >> end [ghoti@pc ~/tmp]$ 

The sed command $r two causes sed to slurp in the file named «two» after processing the last line of input (which in this case is from the file «one»).

Note that this merges one file into the stream of another file, but sed’s «standard output» ( stdout ) is what contains the full/combined stream. You can redirect that output to a file per Ignacio’s answer if that’s what you want.

Читайте также:  Linux make system user

Источник

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.

@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.

Читайте также:  Oracle and linux support

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.

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.

Источник

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