Lucielle
Lucielle

Reputation: 53

Finding a pattern, then executing a line change only after the pattern

I have a file of the like:

H 1 2 3 4
H 1 2 3 4
C 1 2 3 4
 $END

 $EFRAG
COORD=CART
FRAGNAME=H2ODFT
O 1 2 3 4
H 1 2 3 4
H 1 2 3 4
FRAGNAME=H2ODFT
O 1 2 3 4
H 1 2 3 4
H 1 2 3 4

I want to remove the column "1" from the lines only after the $EFRAG line. and add a label to the O H H as well. My expected output is:

H 1 2 3 4
H 1 2 3 4
C 1 2 3 4
 $END

 $EFRAG
COORD=CART
FRAGNAME=H2ODFT
Oa  2 3 4
Hb  2 3 4
Hc  2 3 4
FRAGNAME=H2ODFT
Oa  2 3 4
Hb  2 3 4
Hc  2 3 4

I'm new to coding in bash, and I'm not quite sure where to start.

I was thinking of piping a grep command to a sed command, but I'm not sure how that syntax would look. Am also trying to learn awk, but that syntax is even more confusing to me. Currently trying to read a book on it's capabilities.

Any thoughts or ideas would be greatly appreciated!

L

Upvotes: 2

Views: 76

Answers (3)

potong
potong

Reputation: 58473

This might work for you (GNU sed):

sed -E '1,/\$EFRAG/b;/^O/{N;N;s/^(O) \S+(.*\nH) \S+(.*\nH) \S+/\1a\2b\3c/}' file

Do not process lines from the start of the file until after encountering one containing $EFRAG.

If a line begins O, append the next two lines and then using pattern matching and back references, format those lines accordingly.

Upvotes: 0

RomanPerekhrest
RomanPerekhrest

Reputation: 92854

Use the following awk processing:

awk '$0~/\$EFRAG/ {
    start = 1;  # marker denoting the needed block
    split("a b c", suf);  # auxiliary array of suffixes
}
start {
    if (/^FRAGNAME/) idx = 1;  # encountering subblock
    if (/^[OH]/) {  # if starting with O or H char
        $2 = "";
        $1 = $1 suf[idx++];
    }
}1' test.txt

H 1 2 3 4
H 1 2 3 4
C 1 2 3 4
 $END

 $EFRAG
COORD=CART
FRAGNAME=H2ODFT
Oa  2 3 4
Hb  2 3 4
Hc  2 3 4
FRAGNAME=H2ODFT
Oa  2 3 4
Hb  2 3 4
Hc  2 3 4

Upvotes: 2

Jetchisel
Jetchisel

Reputation: 7801

If ed is available/acceptable.

The script.ed (name it to your own hearts content) something like:

/\$EFRAG$/;$g/^O /s/^\([^ ]*\) [^ ]* \(.*\)$/\1a  \2/\
/^H /s/^\([^ ]*\) [^ ]* \(.*\)$/\1b  \2/\
/^H /s/^\([^ ]*\) [^ ]* \(.*\)$/\1c  \2/
,p
Q

Now run

ed -s file.txt < script.ed

  • Change Q to w if in-place editing is required.

  • Remove the ,p to silence the output.

Upvotes: 0

Related Questions