Monday, June 6, 2022

[SOLVED] Bash: Delete last character from line if certain condition is fulfilled and if the line is between matches

Issue

I have a large file coord that is as follows:

$coord
   -6.81387808414325      5.82189470091282     -1.45477353169903  c f
    3.12250219010826      1.39239934150351      0.78451413146001  o f
   -4.76572488013335     -1.67551810949494     -1.58797087759328  c f
   -0.15061495158492     -2.18614667480844     -2.60227003662941  c f
    etc...
    9.21060449992324     -2.77968508411378      0.71587738888748  h f
    5.87109372056745     -2.67040600177892      0.54514819243204  h f
    7.70747476642116     -1.85827163328137     -2.12317155170529  h f
    3.16053583847830      1.75657003778612      4.21784993053015  h
    3.20523873898751      2.06642906155866      6.03962166222879  o
    3.84518636016769      0.52341324778083      6.76769535558585  h
$intdef
# definitions of internal coordinates
   1 f  1.0000000000000 stre    6   21           val=   2.05908
   2 f  1.0000000000000 stre    6   53           val=   2.07110
   3 f  0.0463401612403 bend   53   21    6      val=   1.20720
        0.5016372600998 bend    7   21    6
        0.4983829790270 bend    7   53    6
  etc...

There are keywords that start with $ such as $coord and $intdef. What I want to do is to delete the f from each line after $coord. So the output should be:

$coord
   -6.81387808414325      5.82189470091282     -1.45477353169903  c
    3.12250219010826      1.39239934150351      0.78451413146001  o
   -4.76572488013335     -1.67551810949494     -1.58797087759328  c
   -0.15061495158492     -2.18614667480844     -2.60227003662941  c
    etc...
    9.21060449992324     -2.77968508411378      0.71587738888748  h
    5.87109372056745     -2.67040600177892      0.54514819243204  h
    7.70747476642116     -1.85827163328137     -2.12317155170529  h
    3.16053583847830      1.75657003778612      4.21784993053015  h
    3.20523873898751      2.06642906155866      6.03962166222879  o
    3.84518636016769      0.52341324778083      6.76769535558585  h
$intdef
# definitions of internal coordinates
   1 f  1.0000000000000 stre    6   21           val=   2.05908
   2 f  1.0000000000000 stre    6   53           val=   2.07110
   3 f  0.0463401612403 bend   53   21    6      val=   1.20720
        0.5016372600998 bend    7   21    6
        0.4983829790270 bend    7   53    6
  etc...

The fs should only be deleted after the keyword $coord but not after any other keyword. Also nothing else should be removed. Just the fs. So I can just find the keyword $coord and stop deleting the fs after the next keyword. I tried to do this in bash. I figured out that I can delete the last column with awk:

awk 'NF{NF=-1};1'

And I can find the lines where f is with sed:

sed -n '/$coord/,/\$/{/$coord/!{/\$/!p}}'

I tried to make a script but I am not able to figure out how I could use these to get the correct output. Or is there some easier way to do this? Can anyone help?


Solution

You can use awk for that:

awk -v RS='$' -v ORS='$' '/^coord\n/ {gsub(/ f\n/,"\n")} 1' file


Answered By - Fravadona
Answer Checked By - Katrina (WPSolving Volunteer)