简体   繁体   中英

SED Replace after certain pattern - value in brackets

I have files where i need to replace all occourences of AC %blabla% with AC (%blabla%+PAR) .

ROT: S 3    BL 3900   SPEED 20
    BEN: L 15   
         
ROT: S 2    BLL (DimZ/2+25) BLR (DimZ/2-29) SPEED 20                 
    BEN: L 14-0.5 A 116  AC -1
    
 ROT: S 2   BLR (DimZ/2-29) BLL (DimZ/2-20) SPEED 20                   
     CLA: L 133 A 64    AC -1 
     
ROT: S 1    BLL (DimZ/2-29) BLR (DimZ/2+25) SPEED 20        
    BEN: L 11-0.5  AC -90
    BEN: L 95   AC 1.5 

Eg: AC -1 should be AC (-1+PAR) afterwards. AC 90 should be AC (90+PAR) afterwards.

What i've tried is:

sed "s/\( AC"."\)/\1(/"

But that doesn't even always add the "("... I get:

ROT: S 3    BL 3900   SPEED 20
    BEN: L 15   
         
ROT: S 2    BLL (DimZ/2+25) BLR (DimZ/2-29) SPEED 20                 
    BEN: L 14-0.5 A 116  AC (-1
    
 ROT: S 2   BLR (DimZ/2-29) BLL (DimZ/2-20) SPEED 20                   
     CLA: L 133 A 64    AC -1 
     
ROT: S 1    BLL (DimZ/2-29) BLR (DimZ/2+25) SPEED 20        
    BEN: L 11-0.5  AC (-90
    BEN: L 95   AC (1.5

Could someone please help me?

Thank you.

$ sed -E 's/(AC )([^ ]*)/\1(\2+PAR)/' ip.txt
ROT: S 3    BL 3900   SPEED 20
    BEN: L 15   
         
ROT: S 2    BLL (DimZ/2+25) BLR (DimZ/2-29) SPEED 20                 
    BEN: L 14-0.5 A 116  AC (-1+PAR)
    
 ROT: S 2   BLR (DimZ/2-29) BLL (DimZ/2-20) SPEED 20                   
     CLA: L 133 A 64    AC (-1+PAR) 
     
ROT: S 1    BLL (DimZ/2-29) BLR (DimZ/2+25) SPEED 20        
    BEN: L 11-0.5  AC (-90+PAR)
    BEN: L 95   AC (1.5+PAR) 
  • -E to enable Extended Regular Expressions
    • Use sed 's/\\(AC \\)\\([^ ]*\\)/\\1(\\2+PAR)/' if -E isn't supported
  • (AC ) to match and capture AC followed by space
    • use ( AC ) to avoid partial match or use \\b(AC ) if word boundary is supported
  • ([^ ]*) to capture non-space characters
  • \\1(\\2+PAR) required output format

What's wrong with OP's attempt:

  • "s/\\( AC"."\\)/\\1(/" will be treated as concatenation of s/\\( AC followed by . followed by \\)/\\1(/
    • can be simplified to sed 's/\\( AC.\\)/\\1(/' --> use single quotes unless double is required
  • \\( AC.\\) will match space followed by AC followed by any character only once
  • \\1( will give you captured portion followed by (

You can use the following POSIX BRE compliant regex with sed :

sed "s/\( AC \)\([^[:space:]]*\)/\1(\2+PAR)/" file

See the online sed demo

If you have GNU sed , I suggest

sed -E "s/\b(AC\s+)(\S+)/\1(\2+PAR)/" file

See another demo .

Regex details

  • \\( AC \\) - Group 1: space, AC , space (so, no match for BAC , for example)
  • \\([^[:space:]]*\\) - Group 2: zero or more non-whitespace chars
  • \\1(\\2+PAR) - the replacement is the concatenated Group 1 value + ( + Group 2 value and +PAR) .

GNU sed regex details

  • \\b - a word boundary
  • (AC\\s+) - Group 1: AC and one or more whitespaces
  • (\\S+) - Group 2: one or more non-whitespace chars.

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