Jay Taylor's notes
back to listing indexAppending a line to a file only if it does not already exist
[web search]- Home
-
- Public
- Stack Overflow
- Tags
- Users
- Jobs
-
I need to add the following line to the end of a config file:
include "/configs/projectname.conf"
to a file called lighttpd.conf
I am looking into using sed
to do this, but I can't work out how.
How would I only insert it if the line doesn't already exist?
Just keep it simple :)
grep + echo should suffice:
grep -q -F 'include "/configs/projectname.conf"' foo.bar || echo 'include "/configs/projectname.conf"' >> foo.bar
Edit: incorporated @Cerin suggestion.
NOTE: for "editors" changing my answer: if you have an alternative solution give your own answer! Editing is intended for clarifying, formatting, better English and so on! Don't change the answer given by others! (thank you)
-
-
FYI, using -v and && doesn't look to do the trick, whereas || without -v works. – bPizzi Aug 25 '10 at 8:21
-
This only works for very simple lines. Otherwise, grep interprets most non-alpha characters in your line as patterns, causing it to not detect the line in the file. – Cerin Jul 10 '14 at 20:34
-
-
Beautiful solution. This also works for triggering more complicated expressions, of course. Mine uses the
echo
to trigger acat
of a multiline heredoc into a config file. – Eric Lawler Jun 15 '15 at 16:10
This would be a clean, readable and reusable solution using grep
and echo
to add a line to a file only if it doesn't already exist:
LINE='include "/configs/projectname.conf"'
FILE=lighttpd.conf
grep -qF -- "$LINE" "$FILE" || echo "$LINE" >> "$FILE"
-
If it's to a file where you need root permissions:
sudo grep -qF "$LINE" "$FILE" || echo "$LINE" | sudo tee -a "$FILE"
– nebffa Dec 8 '17 at 0:50 -
-
@zsero: good point! I added
--
in the grep command, so it will not interpret a $LINE starting with a dash as options any more. – rubo77 Feb 7 at 1:05
Here's 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
-
For a command that replaces a partial string with the complete/updated config file entry, or appends the line as needed:
sed -i -e '\|session.*pam_mkhomedir.so|h; ${x;s/mkhomedir//;{g;tF};a\' -e 'session\trequired\tpam_mkhomedir.so umask=0022' -e '};:F;s/.*mkhomedir.*/session\trequired\tpam_mkhomedir.so umask=0022/g;' /etc/pam.d/common-session
– bgStack15 May 31 '16 at 16:01 -
Nice, it helped me a lot +1. could you please, explain your sed expression ? – Rahul Jun 10 '16 at 10:39
-
I'd love to see an annotated explanation of this solution. I've used
sed
for years but mostly just thes
command. Thehold
andpattern
space swaps are beyond me. – nortally Jun 24 '16 at 15:50
If writing to a protected file, @drAlberT and @rubo77 's answers might not work for you since one can't sudo >>
. A similarly simple solution, then, would be to use tee --append
:
LINE='include "/configs/projectname.conf"'
FILE=lighttpd.conf
grep -qF "$LINE" "$FILE" || echo "$LINE" | sudo tee --append "$FILE"
use awk
awk 'FNR==NR && /configs.*projectname\.conf/{f=1;next}f==0;END{ if(!f) { print "your line"}} ' file file
-
-
It's
file file
because it makes two passes over the same file.NR==FNR
is true on the first pass, but not the second. This is a common Awk idiom. – tripleee Mar 15 '17 at 14:12
another sed solution is to always append it on the last line and delete a pre existing one.
sed -e '$a\' -e '<your-entry>' -e "/<your-entry-properly-escaped>/d"
"properly-escaped" means to put a regex that matches your entry, i.e. to escape all regex controlls from your actuall entry, i.e. to put a backslash infront of ^$/*?+().
this might fail on the last line of your file or if there's no tangling newline, I'm not sure, but that could be dealed with by some nifty branching...
-
Nice one-liner, short and easy to read. Works great for updating etc/hosts:
sed -i.bak -e '$a\' -e "$NEW_IP\t\t$HOST.domain\t$HOST" -e "/.*$HOST/d" /etc/hosts
– Noam Manos Apr 26 at 16:38
If, one day, someone else have to deal with this code as "legacy code", then that 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
I needed to edit a file with restricted write permissions so needed sudo
. working from ghostdog74's answer and using a temp 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
-
This doesn't look correct, it will lose the other lines from the file when the config line is missing. – tripleee Mar 15 '17 at 14:13
Your Answer
Not the answer you're looking for? Browse other questions tagged linux sed terminal or ask your own question.
asked |
8 years, 1 month ago |
viewed |
55,911 times |
active |
Get the weekly newsletter! In it, you'll get:
- The week's top questions and answers
- Important community announcements
- Questions that need answers
see an example newsletter
Linked
Related
Hot Network Questions
-
Nobody likes this compound word
-
To ferment or not to ferment for no alcohol
-
Will declining my company's many social events negatively influence my career?
-
In the Battle of Department of Mysteries, why were only 5 Order members sent to rescue Harry Potter?
-
how best to structure/manage hundreds of 'in-game' characters?
-
Is a CO2 fire extinguisher safe to use to represent offensive magic or breath weapons in LARP?
-
Elegant way of partitioning in two starting from the second element?
-
If I was Schrödinger's cat, what would I feel?
-
Were later MS-DOS versions still implemented in x86 assembly?
-
How are post apocalyptic police/paramilitary force funded?
-
The DUP have threatened to “vote down the budget” - but what does this mean?
-
How do you write unit tests for code with difficult to predict results?
-
Why would post-apocalyptic men be twice as large as women?
-
How to write female characters with agency?
-
Get previous business day in a DataFrame
-
What are these huge ‘fields’ of light just north of Amsterdam?
-
Why doesn't Graham believe in aliens?
-
My 3 year old daughter thinks she is white. Should I tell her she's not?
-
Arbitrary Length Hashing
-
What is the difference between "I still use" vs "I am still using" in this sentence?
-
Eliminate query on Custom metadata type?
-
How to communicate to my aunt that she made an honest mistake when buying food for a family meal?
-
How to deal with discount when invoice has multiple line items and multiple tax rates?
-
PS4 - disc and digital copy of the same game
site design / logo © 2018 Stack Exchange Inc; user contributions licensed under cc by-sa 3.0 with attribution required. rev 2018.10.10.31890