[SOLVED] sed stop insert the line after the first occurrence of the pattern
Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
sed stop insert the line after the first occurrence of the pattern
Lets take such text file named "/tmp/test":
Code:
yyyy-1
xxxx-2
xxxx-3
zzzz-4
xxxx-5
I want to insert additional line containing "aaaa-6" before first occurrence of line containing string "xxxx" at the beginning of line. But only one time, as I wrote at first occurrence.
For this purpose I want to use the script like this:
Code:
#!/bin/sh
entry="aaaa-6"
sed -i "/^xxxx*/a $entry" /tmp/test
But this script insert after each occurrence of pattern.
Any idea how to stop sed after first occurrence?
Notice that /bin/sh is used (busybox) not bash.
Sed works on individual lines at a time - if you're to working on multiple lines, a different tool might be a better fit.
However, GNU sed does have -z to treat the line delimiter as nul char instead of newlines; I don't know if Busybox sed has that, but if it does you can combine it with passing 1 to s/// to instruct it to substitute once, like so:
Code:
sed -z 's/\nxxx[^\n]*\n/\nINSERTED\0/1' input-file
The \0 includes the matched text in the replacement, making this a prepend operation. (Swap places with \0 and \n to make it an append instead.)
If the -z flag isn't available, but using other tools is an option, awk can easily use a flag as part of its condition:
#!/bin/sh
entry="aaaa-6"
sed -i "/^xxxx*/a $entry" /tmp/test
But this script insert after each occurrence of pattern.
Any idea how to stop sed after first occurrence?
The "a" in the sed command means "append". There is an "i" command, which inserts before a line.
I am not sure if sed can be asked to perform the insertion only at the first occurrence of the line pattern. Check the sed manual (link in my signature).
Normally one would simply use q to stop after a sed sub-command. Doesn't work here because:
- the append consumes everything as its text - including the " ; q}". Didn't know that until I just tested.
- even if it did work, the quit will truncate the file due to the use of "-i".
The only way I could get it done was to read the entire file into the pattern space and change only the first occurrence which sed supports (i.e. don't use append at all).
The "a" in the sed command means "append". There is an "i" command, which inserts before a line.
I am not sure if sed can be asked to perform the insertion only at the first occurrence of the line pattern. Check the sed manual (link in my signature).
Yep. a stands for append, i stands for insert. But the output result is the same in both cases.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.