1

I have a file that looks like this:

...
%ldirs
(list of line-separated directories)
...

With a shell script, I need to add a directory to the list in that file, but only if that directory is not already in the list. Here's the catch: The directory in question must come from a variable $SOME_PATH.

I thought about using the patch utility, but to do that I would have to generate the patch file dynamically to add "+$SOME_PATH". The other problem is that I do not know the "after context" or the line number of "%ldirs", so generating the patch file is problematic.

Is there another option?

Tweaked answer - Thanks to Rob:

line=$(grep "$SOME_PATH" /path/to/file)
if [ $? -eq 1 ]
    then
    sed -i "/%ldirs/ a\\$SOME_PATH" /path/to/file
fi

Final answer - Thanks to tripleee:

fgrep -xq "$SOME_PATH" /path/to/file || sed -i "/%ldirs/ a\\$SOME_PATH" /path/to/file
Tergiver
  • 14,171
  • 3
  • 41
  • 68
  • I hotly debated with myself: stackoverflow, superuser, stackoverflow, superuser. Apparently I got it wrong. – Tergiver Feb 02 '12 at 21:58

1 Answers1

2

line=$(grep "$SOME_PATH" %ldirs)
if [ $? -eq 1 ]
    then
    echo "$SOME_PATH" >> %ldirs
fi

something like this should work, it worked fine for me. I'm sure there are other ways to write it, too.

line=$(grep "$SOME_PATH" /path/to/file)
if [ $? -eq 1 ]
    then
    sed -i 's/%lsdir/%lsdir\n"$SOME_PATH"/' /path/to/file
fi

should work. It'll find %lsdir and replace it with %lsdir(newline)$SOME_PATH (not sure if quotes are needed on $SOME_PATH here, pretty sure they aren't)

Rob
  • 2,779
  • 5
  • 23
  • 34
  • `%ldirs` is part of the file contents, not the file name. I think it's like `[section]` in INI files. – Daniel Beck Feb 02 '12 at 16:53
  • Oh, that makes sense. :/ that makes things a bit more difficult then, doesn't it. – Rob Feb 02 '12 at 16:54
  • or not. testing something else really quickly. – Rob Feb 02 '12 at 16:55
  • Yes, it's just like `[section]` in INI files. Just a wee bit more difficult ;) – Tergiver Feb 02 '12 at 17:05
  • It's close. `$SOME_PATH` is not being expanded in the `sed` line, it's adding it raw. – Tergiver Feb 02 '12 at 17:34
  • try ${SOME_PATH} or replace the single quotes around the sed with double quotes, `sed "s|%lsdir|%lsdir/n$SOME_PATH|"` instead. – Rob Feb 02 '12 at 17:55
  • After scrounging the SED docs, I got it. Instead of the `s///` expression, there is an append expression `//a`. See my edit above. – Tergiver Feb 02 '12 at 18:01
  • Btw, the problem for the `s///` expression is that $SOME_PATH contains '/' characters. – Tergiver Feb 02 '12 at 18:05
  • I had problems getting a newline in with append, glad you got it figured out. – Rob Feb 02 '12 at 18:58
  • 3
    `fgrep -xq "$SOME_PATH" /path/to/file || sed -i 's!%ldirs%&\n'"$SOME_PATH"'!' /path/to/file` ... note the fixed quoting in the `sed` script, and the use of `fgrep -x` to look for the whole line, not a partial match. – tripleee Feb 02 '12 at 20:18
  • @tripleee Thanks for that. My version didn't work with the -e script argument `#/bin/bash -e` (because of grep returning 1) so I had turned it off. Now I can turn it back on. – Tergiver Feb 02 '12 at 21:51
  • Might still do the erong thing if `SOME_PATH` is present but not in the `%ldirs` section. A more-complex `sed` script will be necessary in that case. It's not that hard, but perhaps this is close enough for the real world already. – tripleee Feb 03 '12 at 09:21
  • It works for both cases (there or not there). I didn't check if the script will continue past this line as it's the last line in the script; I don't really care if it doesn't. – Tergiver Feb 03 '12 at 16:20