user333422
user333422

Reputation: 377

Replace particular string at fixed position using sed

I have a simple text file containing several lines of data where each line has got exactly 26 characters. E.g.

10001340100491938001945591
10001340100491951002049591
10001340100462055002108507
10001340100492124002135591
10001340100492145002156507
10001340100472204002205591

Now, I want to replace 12th and 13th character if only these two characters are 49 with characters 58.

I tried it like this:

sed 's/^(.{12})49/\58/' data.txt

but am getting this error:

sed: -e expression #1, char 18: invalid reference \5 on `s' command's RHS

Thanks in advance

Upvotes: 5

Views: 40207

Answers (3)

Jotne
Jotne

Reputation: 41456

If you like to try an awk solution:

awk 'substr($0,12,2)==49 {$0=substr($0,1,11)"58"substr($0,14)}1' file
10001340100581938001945591
10001340100581951002049591
10001340100462055002108507
10001340100582124002135591
10001340100582145002156507
10001340100472204002205591

Upvotes: 5

Floris
Floris

Reputation: 46365

In your expression you are replacing the first 14 characters (if you got it right). But you need to replace 11 plus the two (12th, 13th). More importantly, sed is fussy about escaping brackets, so you need backslashes in front of \( and { etc. Finally - the number of the capture group is 1. You omitted that number.

Putting it all together, you get

sed 's/^\(.\{11\}\)49/\158/'

There are flags you can use in sed to make the expressions more "regular" (changing the meaning of ( vs \(). What flag that is depends on your platform (version of sed), I believe.

Upvotes: 2

Lev Levitsky
Lev Levitsky

Reputation: 65791

The captured group is \1, so you want to put the 11 (not 12) characters, then 58:

sed -E 's/^(.{11})49/\158/' data.txt

You also need -E or -r if you don't want to escape square and curly brackets.

With your input, the command changes 49 to 58 in lines 1, 2, 4 and 5.

Upvotes: 7

Related Questions