Using Regex to replace or add a line to a file | Linux shell script

I am trying to find the right command to execute in a file that looks something like this: (e.g. .cshrc files)

setenv BLAH foo

I need a command to replace the line where it detects the line BLAH, and replace the entire line as follows:

setenv BLAH newfoo 

If BLAHdoes not exist in the file, add it to the file.

I played with sedas such, but that does not reach my goal.

sed 's/^.*?BLAH.*/setenv BLAH newfoo/g' text.txt > text.tmp && mv text.tmp text.txt

I also played with awk, and also could not get the team to work exactly the way I want it.

awk -v s="setenv BLAH newfoo" '/^BLAH/{f=1;$0=s}7;END{if(!f)print s}' text.txt > text.tmp && mv text.tmp text.txt

Any ideas on how to achieve this would be great.

UPDATE

I am trying to make this script work as expected.

script

ARG1="$1"
sed -i "/BLAH/s/^.*\$/setenv ${ENV_KEY} ${ENV_VAL}/g" file.txt
# If the BLAH keyword isnt there, append the file then.
grep -v -q "BLAH" file.txt && echo "setenv BLAH ${ARG1}" >> file.txt

file.txt (default)

setenv BLAH randomstring

use script

script.sh newvalue

file.txt()

setenv BLAH newvalue

script, , . , arg1 sed.

+4
4

script:

sed  '/BLAH/{s/ \w+$/ newfoo/;h};${x;/BLAH/ba;x;s/$/\nsetenv BLAH newfoo/;x;:a;x}'

sed -e '
    /^\(\|.*\W\)BLAH\(\W.*\|\)$/{  # lines matching word BLAH
      s/ \w\+$/ newfoo/; # replace last word by "newfoo"
      h;         # Store for not adding them at end of file 
    };
    ${           # On last line...
      x;         # Swap stored line with current line
      /BLAH/ba;  # if match, branch to label a:
      x;         # Swap back
      s/$/\nsetenv BLAH newfoo/; # Replace end of line with newline...
      x;         # Swap again
    :a;          # Label a:
      x          # Swap back
}'

:

sed -e'/BLAH/{h};${x;/BLAH/ba;x;s/$/\nsetenv BLAH newfoo/;x;:a;x}' -i text.txt

, BLAH:

sed -e '
    /^\(.*\W\|\)BLAH\(\W.*\|\)$/{h}; # Store lines matching word BLAH
    ${           # On last line...
      x;         # Swap stored line with current line
      /./ba;  # if match, branch to label a:
      x;         # Swap back
      s/$/\nsetenv BLAH newfoo/; # Replace end of line with newline...
      x;         # Swap again
    :a;          # Label a:
      x          # Swap back
    }'  <(echo BLAH=foo;seq 1 4)
BLAH=foo
1
2
3
4

sed -e '
    /^\(.*\W\|\)BLAH\(\W.*\|\)$/{h}; # Store lines matching word BLAH
    ${           # On last line...
      x;         # Swap stored line with current line
      /./ba;  # if match, branch to label a:
      x;         # Swap back
      s/$/\nsetenv BLAH newfoo/; # Replace end of line with newline...
      x;         # Swap again
    :a;          # Label a:
      x          # Swap back
    }'  <(echo BLAHBLAH=foo;seq 1 4)
BLAHBLAH=foo
1
2
3
4
setenv BLAH newfoo

, BLAH .. , 1- , . , char, , .

script

:

sedcmd='/^\(.*\W\|\)%s\(\W.*\|\)$/{s/ \w\+$/ %s/;h};'
sedcmd+='${x;/./ba;x;s/$/\\nsetenv %s %s/;x;:a;x}'
varnam=BLAH
varcnt=foo
filnam=/tmp/file.txt
printf -v sedcmd "$sedcmd" ${varnam} ${varcnt} ${varnam} ${varcnt}
sed -e "$sedcmd" -i "$filnam"

-i ...

, :

sed -e "$sedcmd" <(echo setenv BLAH oldfoo;seq 1 4) 
setenv BLAH foo
1
2
3
4

sed -e "$sedcmd" <(echo setenv BLAHBLAH oldfoo;seq 1 4) 
setenv BLAHBLAH oldfoo
1
2
3
4
setenv BLAH foo
+5

awk :

awk -v kw='BLAH' '$2 == kw{$3="newfoo"; seen=1} 1;
      END{if (!seen) print "setenv " kw " newfoo"}' file

-v kw=....

END , .

+1

, sed , grep , .

.

ENV_KEY=BLAH
ENV_VAL=foo
sed -i "/BLAH/s/^.*\$/setenv ${ENV_KEY} ${ENV_VAL}/g" text.tmp
! grep -q "${ENV_KEY}" text.tmp && echo "setenv ${ENV_KEY} ${ENV_VAL}" >> text.tmp

sed BLAH, , ^.*$. -i sed .

+1

(GNU sed):

sed '/blah/h;//s/foo/newfoo/;$!b;G;/blah/!s/.$/&setenv blah newfoo/;t;P;d' file

blah , (HS) newfoo foo. , . HS blah. append setenv blah newfoo .

+1

Source: https://habr.com/ru/post/1615310/


All Articles