Adding a line to a file only if it does not already exist

I need to add the following line to the end of the configuration file:

include "/configs/projectname.conf" 

to a file called lighttpd.conf

I use sed for this, but can't figure out how to do this.

How can I insert it only if the row does not exist yet?

+128
linux terminal sed
Aug 24 '10 at 13:40
source share
10 answers

Just be easier :)

grep + echo should be enough:

 grep -qxF 'include "/configs/projectname.conf"' foo.bar || echo 'include "/configs/projectname.conf"' >> foo.bar 

Edit: @cerin and @ thijs-wouters suggestions are included.

+239
Aug 24 '10 at 13:53
source share

This would be a clean, readable and reusable solution, using grep and echo to add a line to the file only if it does not already exist:

 LINE='include "/configs/projectname.conf"' FILE='lighttpd.conf' grep -qF -- "$LINE" "$FILE" || echo "$LINE" >> "$FILE" 
+68
Jan 19 '15 at 9:22
source share

Here is a sed version:

 sed -e '\|include "/configs/projectname.conf"|h; ${x;s/incl//;{g;t};a\' -e 'include "/configs/projectname.conf"' -e '}' file 

If your string is in a variable:

 string='include "/configs/projectname.conf"' sed -e "\|$string|h; \${x;s|$string||;{g;t};a\\" -e "$string" -e "}" file 
+12
Aug 24 '10 at 19:04
source share

When writing to a protected file, @drAlberT and @ rubo77 answers may not work for you, since you cannot sudo >> . A similarly simple solution would be to use tee --append :

 LINE='include "/configs/projectname.conf"' FILE=lighttpd.conf grep -qF "$LINE" "$FILE" || echo "$LINE" | sudo tee --append "$FILE" 
+8
Mar 31 '17 at 16:28
source share

If one day someone else has to deal with this code as a "legacy code", then this person will be grateful if you write a less exoteric code such as

 grep -q -F 'include "/configs/projectname.conf"' lighttpd.conf if [ $? -ne 0 ]; then echo 'include "/configs/projectname.conf"' >> lighttpd.conf fi 
+6
May 01 '18 at 23:54
source share

another sed solution always adds it to the last line and removes the existing one.

 sed -e '$a\' -e '<your-entry>' -e "/<your-entry-properly-escaped>/d" 

“properly escaped” means putting a regular expression that matches your record, i.e. avoid all the control elements of the regular expression from your entry into the application, i.e. put a backslash under the character ^ $ / *? + ().

it may fail on the last line of your file or if there is no confusing new line, I'm not sure, but this could be dealt with with a little fork ...

+5
May 08 '14 at 18:16
source share

use awk

 awk 'FNR==NR && /configs.*projectname\.conf/{f=1;next}f==0;END{ if(!f) { print "your line"}} ' file file 
+3
Aug 24 '10 at 14:05
source share

Answers using grep are incorrect. You need to add the -x option so that it matches the entire line, otherwise lines such as #text to add will still match when looking to add the exact text to add .

So the correct solution looks something like this:

 grep -qxF 'include "/configs/projectname.conf"' foo.bar || echo 'include "/configs/projectname.conf"' >> foo.bar 
+1
Dec 30 '18 at 11:06
source share

Using sed: it will be inserted at the end of the line. You can also pass variables, as usual, of course.

 grep -qxF "port=9033" $light.conf if [ $? -ne 0 ]; then sed -i "$ a port=9033" $light.conf else echo "port=9033 already added" fi 

Using oneliner sed

 grep -qxF "port=9033" $lightconf || sed -i "$ a port=9033" $lightconf 

Using echo may not work as root, but it will work like that. But this will not allow you to automate the process if you want to do this, because it can request a password.

I had a problem when I tried to edit from the root for a specific user. Just adding $username used to be a fix for me.

 grep -qxF "port=9033" light.conf if [ $? -ne 0 ]; then sudo -u $user_name echo "port=9033" >> light.conf else echo "already there" fi 
+1
Feb 27 '19 at 5:57
source share

I needed to edit a file with limited write permissions, so sudo needed. working from ghostdog74 and using a temporary file:

 awk 'FNR==NR && /configs.*projectname\.conf/{f=1;next}f==0;END{ if(!f) { print "your line"}} ' file > /tmp/file sudo mv /tmp/file file 
0
Apr 29 '14 at 14:44
source share



All Articles