简体   繁体   中英

SED - Insert saved value after certain pattern when a specific string doesn't exist in the file

I have files that look similar to this :

LET: DimX   (2660.0)
LET: DimZ   (1050.0)
LET: DimS   (0.8)
LET: DREHEN (20)

DIM: X DimX
     Z DimZ+0.5
     S DimS
     

REF: X1 FOD-23.24
     X2 FOD-23.24
     Z1 FOD-24.86
     Z2 FOD-24.86

POS: CENT_FUNC 1
     QSU 10 QSD 10
     TURN_AROUND

And like this - note the STAINLESS in the 2nd one:

LET: DimX   (2660.0)
LET: DimZ   (1050.0)
LET: DimS   (0.7)
LET: DREHEN (20)

DIM: X DimX
     Z DimZ+0.5
     S DimS
     STAINLESS

REF: X1 FOD-23.24
     X2 FOD-23.24
     Z1 FOD-24.86
     Z2 FOD-24.86

POS: CENT_FUNC 1
     QSU 10 QSD 10
     TURN_AROUND

I want to save the value in Brackets in the line matching LET: DimS ( XX ) and insert a new line MAT: 'XX correction ' - where XX is the save value. after S DimS

  • But only if the file whole doesn't contain the string STAINLESS.

So this should be the outcome for the 1st example :

LET: DimX   (2660.0)
LET: DimZ   (1050.0)
LET: DimS   (0.8)
LET: DREHEN (20)

DIM: X DimX
     Z DimZ+0.5
     S DimS
     MAT: '0.8 correction'


REF: X1 FOD-23.24
     X2 FOD-23.24
     Z1 FOD-24.86
     Z2 FOD-24.86

POS: CENT_FUNC 1
     QSU 10 QSD 10
     TURN_AROUND

Outcome of the 2nd example should stay as it was as it contains STAINLESS:

LET: DimX   (2660.0)
LET: DimZ   (1050.0)
LET: DimS   (0.7)
LET: DREHEN (20)

DIM: X DimX
     Z DimZ+0.5
     S DimS
     STAINLESS

REF: X1 FOD-23.24
     X2 FOD-23.24
     Z1 FOD-24.86
     Z2 FOD-24.86

POS: CENT_FUNC 1
     QSU 10 QSD 10
     TURN_AROUND

I've tried this to add the line after S DimS pattern:

sed -i -E '/S DimS/I a  \\t MAT: "'"0.8 correction"'"'

But that just gives me:

LET: DimX   (2660.0)
LET: DimZ   (1050.0)
LET: DimS   (0.8)
LET: DREHEN (20)

DIM: X DimX
     Z DimZ+0.5
     S DimS
     MAT: "0.8 correction"

REF: X1 FOD-23.24
     X2 FOD-23.24
     Z1 FOD-24.86
     Z2 FOD-24.86

POS: CENT_FUNC 1
     QSU 10 QSD 10
     TURN_AROUND

And:

    LET: DimX   (2660.0)
LET: DimZ   (1050.0)
LET: DimS   (0.7)
LET: DREHEN (20)

DIM: X DimX
     Z DimZ+0.5
     S DimS
     MAT: "0.8 correction"
     STAINLESS

REF: X1 FOD-23.24
     X2 FOD-23.24
     Z1 FOD-24.86
     Z2 FOD-24.86

POS: CENT_FUNC 1
     QSU 10 QSD 10
     TURN_AROUND

And obvioulsy won't save the value in the brackets...

Can anyone help me please?

Thank you.

If you're amenable to an awk solution, which is often easier than sed when there's logic to perform beyond simple string manipulation ...

# Capture the correction amount
/LET: DimS/ { correction = $3; gsub(/[()]/, "", correction) }

# Get ready to print
$1 == "DIM:" { f = 1 }

# Abort print!!
$1 == "STAINLESS" { f = 0 }

# Now is the time to print the extra line if the flag is still set
NF == 0 && f { printf "     MAT: '%s correction'\n", correction; f = 0 }

# Output the original lines of the file
{ print }

Test first example:

$ awk -f a.awk file
LET: DimX   (2660.0)
LET: DimZ   (1050.0)
LET: DimS   (0.8)
LET: DREHEN (20)

DIM: X DimX
     Z DimZ+0.5
     S DimS
     MAT: '0.8 correction'


REF: X1 FOD-23.24
     X2 FOD-23.24
     Z1 FOD-24.86
     Z2 FOD-24.86

POS: CENT_FUNC 1
     QSU 10 QSD 10
     TURN_AROUND

Try it with your second "STAINLESS" example and you'll see that the extra line is not printed.

This might work for you (GNU sed):

sed -E ':a;N;$!ba;/STAINLESS/b;
    s/^(.*LET:\sDimS\s*\(([^)]*).*\n(\s*)S DimS[^\n]*\n)/\1\3MAT: '\''\2 correction'\''/' file

Gather up the entire file into memory and test it to see if it contains the word STAINLESS . If so, bail out otherwise: using pattern matching insert the required text.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM