Jerry Jerry - 6 months ago 10
Bash Question

Insert line if pattern doesn't match otherwise modify the line with the pattern

Suppose I want to modify a file

foo.ini
with the following
sed
:

bar="hello"

sed -i "
# if there is NZ variable in db2dj.ini, we simply set it to the proper value
s/NZ=*/NZ=$bar/

# if there is no NZ variable, we add NZ_ODBC_INI_PATH variable and set the proper value to it
T add


:add
$ i\NZ_ODBC_INI_PATH=$db2dj_nz_odbc_ini_path

" foo.ini


Suppose
foo.ini
is empty at first. Then I run the
sed
above and I got:

NZ=hello


This is fine. However, if I run the same
sed
command again,
foo.ini
will become:

NZ=hellohello
NZ=hello


My ideal for
sed
command is that:


  1. if there is no
    NZ
    variable, then it add
    NZ=hello
    to it

  2. if there is already
    NZ
    variable with form like
    NZ=hi
    , it will change it to
    NZ=hello

  3. Only when
    NZ=hello
    should appear in
    foo.ini



How do I modify the above
sed
command to achieve this task? I believe my
sed
command works fine with (1) but not with (2) (3)

Many thanks!

Answer

A simple grep check is sufficient:

grep -q '\bNZ=\b' foo.ini > /dev/null 2>&1 && sed -i 's/NZ=.*$/NZ=hello/' foo.ini || echo "NZ=hello" >> foo.ini

The above statement will insert if no variable present. Also it handles substitution if already present with a different/same value.

$ cat foo.ini
cat: foo.ini: No such file or directory
$ grep -q '\bNZ=\b' foo.ini > /dev/null 2>&1 && sed -i 's/NZ=.*$/NZ=hello/' foo.ini || echo "NZ=hello" >> foo.ini
$ cat foo.ini 
NZ=hello
$ grep -q '\bNZ=\b' foo.ini > /dev/null 2>&1 && sed -i 's/NZ=.*$/NZ=hello/' foo.ini || echo "NZ=hello" >> foo.ini
$ cat foo.ini 
NZ=hello
$ vim foo.ini 
$ cat foo.ini 
NZ=hi
$ grep -q '\bNZ=\b' foo.ini > /dev/null 2>&1 && sed -i 's/NZ=.*$/NZ=hello/' foo.ini || echo "NZ=hello" >> foo.ini
$ cat foo.ini 
NZ=hello