Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I need to know if a file aready has line with contents X in it, if not append line. here's the code I've tried.

if ! $(grep 'eval $(perl -I$HOME/foo/lib/perl5 -Mlocal::lib=$HOME/foo)' ~/.bashrc)
    echo 'eval $(perl -I$HOME/foo/lib/perl5 -Mlocal::lib=$HOME/foo)' >> ~/.bashrc
share|improve this question
I answered a similar question on stackoverflow: stackoverflow.com/questions/4479579/… – camh Jan 12 '11 at 13:03
up vote 3 down vote accepted

LINE='eval $(perl -I$HOME/foo/lib/perl5 -Mlocal::lib=$HOME/foo)'

if ! grep -qF "$LINE" file.txt ; then echo "$LINE" >> file.txt ; fi

The $(...) will return the result of the command, not the errorlevel value. Use without command substitution to get the proper return code.

share|improve this answer
The '!' command isn't always available in 'sh', IIRC (yeah, I know you used bash). It might be slightly more idiomatic sh to say: grep -qF "$LINE" file.txt || echo "$LINE" >> file.txt – Hari Jan 12 '11 at 16:23
@Hari: ! wasn't in Bourne, but it is in POSIX. – Gilles Jan 12 '11 at 21:30

To search for a literal string:

line='eval $(perl -I$HOME/foo/lib/perl5 -Mlocal::lib=$HOME/foo)'
if ! grep -q -x -F -e "$line" <"$file"; then
  printf '%s\n' "$line" >>"$file"

-q suppresses grep output (you're only interested in the return status). -x requires the whole line to match. -F searches for a literal string rather than a regexp. -e is a precaution in case $line starts with a -.

share|improve this answer

You may have better luck with awk's index function: it's an equivalent of strstr, so should be well-suited for comparision (as opposed to grep which is for pattern matching).

share|improve this answer

You can do this with sed. The issue is that you need to include the string in the code twice. Once to test it, again to insert it.

sed -i '/eval \$(perl -I\$HOME\/foo\/lib\/perl5 -Mlocal::lib=\$HOME\/foo)/!{ ${ s/$/\neval \$(perl -I\$HOME\/foo\/lib\/perl5 -Mlocal::lib=\$HOME\/foo)/; }; }' /path/to/file
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.