2

Input file:

AAA, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH

Output should be:

AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH

I thought about something like:

awk -F, '{n=split($2,a,":"); a[n]} {$2=$NF","$2}1' OFS=,

But the first "split" uses the right side of the delimiter instead of the left and the copy at the end copies the HHH instead of the BBB.

  • Wait. your expected output and the last line in your question is contrast... can you cross check. – msp9011 Aug 31 '18 at 10:18
  • Do we need XXX or BBB in second field ? – msp9011 Aug 31 '18 at 10:19
  • Output should look like: AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH, second field splitted on the left side of the : and inserted on $2 leaving the initial $2 as $3 – T-One Aug 31 '18 at 11:43
  • I have edited your question. plz crosscheck. – msp9011 Aug 31 '18 at 11:47
2

With single awk:

awk -F'[:,]' '{$3=$2":"$3}1' OFS=, infile
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH
0

Try this:

awk -F, '{n=split($2,a,":"); a[n]} {$2=a[1]","$2}1' OFS=, file
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH

Your assigning last field and a second field to $2 ($2=$NF","$2) instead of assigning fist split in a with the second field ($2=a[1]","$2)

0

A simple non-awk approach

$ ( cut -f1 -d: file ; cut -f2- -d, file ) | paste -sd,
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH
$
0

A quick sed option

sed -r 's/, \w+/&&/'

The \w+ expression matches alphanumerics (in your example the BBB) but not punctuation or whitespace. The & represents the entire match.

Example

echo 'AAA, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH' | sed -r 's/, \w+/&&/'
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH
0
$ awk -F, -v OFS=, '{ for (i=1; i<=NF; ++i) if (split($i, a, ":") > 1) $i = a[1] OFS $i } 1' file
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH

You will have to iterate through all fields, and when you find a field that splits into more than one string when you split on :, then you need to prepend the first part of that split string to the value of that field.

If you know it's always going to be the second field:

$ awk -F, -v OFS=, '{ split($2, a, ":"); $2 = a[1] OFS $2 } 1' file
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH

In your code, n will be the number of strings that the data was split into, so a[n] will be the last (rightmost) :-delimited string in $2.


Using sed:

$ sed 's/\([^,: ]*\):/\1, &/g' file
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH

This would replace any string not containing ,, : or space, and that are followed immediately by a : with itself twice (the second time with the final : included).

Remove the g at the end of the s command if you only ever expect to make a single replacement (as in your example).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.