Sunny
Sunny

Reputation: 103

How to swap only numeric values in each line

I need to swap only numeric values in each line after specific string "PIC" using sed. For example:

hello PIC A(12), and this PIC B(11)

The desired output is :

hello PIC B(11), and this PIC A(12)

The characters "B" and "A" might differ in other lines, but the string PIC is always there.

I am trying to use sed command :

echo "hello PIC A(12), and this PIC B(11)" | sed '/PIC X(12)/s/PIC X(12)/PIC X(11)/g'

but seems not working properly.

All responses are appreciated.

Upvotes: 2

Views: 111

Answers (3)

Ed Morton
Ed Morton

Reputation: 204015

With any POSIX sed:

$ sed 's/\(PIC [[:upper:]]([0-9]*)\)\(.*\)\(PIC [[:upper:]]([0-9]*)\)/\3\2\1/' file
hello PIC B(11), and this PIC A(12)

If you don't have a POSIX sed (e.g. old sed on Solaris) then set LC_ALL=C and change [:upper:] to [A-Z].

Upvotes: 1

user7712945
user7712945

Reputation:

if data in 'd' file, tried on gnu sed

sed -E 's/(hello PIC )(\w+)(\S+, and this PIC )(\w+)/\1\4\3\2/' d

Upvotes: 1

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627103

You may use the substitute command directly since it will only change the lines where the match is found.

Use this POSIX ERE

sed -E 's/(PIC )([A-Z]\([0-9]+\))(.*PIC )([A-Z]\([0-9]+\))/\1\4\3\2/'

Or, POSIX BRE

sed 's/\(PIC \)\([A-Z]([0-9]*)\)\(.*PIC \)\([A-Z]([0-9]*)\)/\1\4\3\2/'

The two versions differ in the parentheses escaping: in POSIX BRE, \(...\) denote capturing groups and ( and ) are matching literal parentheses, while in POSIX ERE, it is vice versa.

POSIX ERE pattern details:

  • (PIC ) - Group 1: PIC and space
  • ([A-Z]\([0-9]+\)) - Group 2: any uppercase ASCII letter, (, 1+ digits, )
  • (.*PIC ) - Group 3: any 0 or more chars, PIC, space
  • ([A-Z]\([0-9]+\)) - Group 4: an uppercase letter, (, 1+ digits, ).

Upvotes: 2

Related Questions