0

I need to search a string in the file like

**abc.def., *

My input file looks like

mn.*, \
gh.*, \
pqrs.* \
fgh.* \
zcv.* \
rp.* \

My output has to be appended if the search string is not present in the file it has to be appended in the file like

mn.*, \
gh.*, \
abc.def.*, \
pqrs.* \
fgh.* \
zcv.* \
rp.* \

How do i do it in the shell script. I am able to search with grep with pattern but not able to add the line. Any quick suggestions would help me Below is my command

grep -q -F "abc.def.*, \" filename
echo $?
user1485267
  • 1,295
  • 2
  • 10
  • 19
  • Does this answer your question? [Appending a line to a file only if it does not already exist](https://stackoverflow.com/questions/3557037/appending-a-line-to-a-file-only-if-it-does-not-already-exist) – shree.pat18 Jun 11 '21 at 03:52
  • It adds in last line if we do that.. But i want the line to be appended before 5 lines from the bottom. – user1485267 Jun 11 '21 at 04:58
  • @user1485267 : You need to specify in your question the precise rule, **where** to insert the new line, instead of just giving an example. – user1934428 Jun 11 '21 at 08:09

2 Answers2

1

This bit of shell will add the line in question after the fifth from the bottom one if it's not already present in the file:

filename=input.txt
if ! grep -qF 'abc.def.*, \' "$filename"; then
    ed -s "$filename" <<'EOF'
$-4a
abc.def.*, \
.
w
EOF
fi

thanks to ed being easily able to set the current line marker to X lines before the last one.

Shawn
  • 47,241
  • 3
  • 26
  • 60
  • Thanks Shawn, But i am looking with the one liner of the command which helps me to do add multiple lines in future. Thanks for your suggestions – user1485267 Jun 16 '21 at 04:38
1

1,

grep -q -F 'abc.def.*, \' filename || tac filename|sed '4aabc.def.*, \\'|tac

If match the pattern abc.def.*, \, it will not execute the command after ||, the first tac will reverse the file lines for append the pattern in 5th line by sed '4a, the last tac will restore the file lines.

2,

grep -q -F 'abc.def.*, \' filename || sed "$(( $( wc -l < filename) -4 )) a abc.def.*, \\\\" filename

Something as the case 1, but this will use wc to index the 5th line and append to that, wc -l < filename will only get the file lines number. The \\\\ for escape and print / in double quotes.

Victor Lee
  • 2,467
  • 3
  • 19
  • 37