Buccaneers Tampa
Buccaneers Tampa

Reputation: 23

replace data after last delimiter of every line using sed or awk

I have a text file A.txt, all lines in which have the same number of fields separated by pipe | delimiter. I need to replace , with | for the data after the last delimiter of each line.

Example:

1,2|3,4|5|6,7,8
1,8|4|6,5,3|4,5

Desired output, (only replace , with | after last delimiter):

1,2|3,4|5|6|7|8
1,8|4|6,5,3|4|5

How to achieve this using sed or awk?

Upvotes: 0

Views: 1963

Answers (2)

Sundeep
Sundeep

Reputation: 23667

$ cat ip.txt 
1,2|3,4|5|6,7,8
1,8|4|6,5,3|4,5

with sed

$ sed -E ':a s/^(.*\|[^,]+),([^|]+)$/\1|\2/g; ta' ip.txt 
1,2|3,4|5|6|7|8
1,8|4|6,5,3|4|5
  • :a and ta to loop sed command until there is a match found
  • ^(.*\|[^,]+) from start of line to | followed by non, characters. * and + will try to match as much as possible
  • , match a comma
  • ([^|]+)$ after the comma, there should not be any | character till end of line


with perl

$ perl -F'\|' -lane '$F[-1] =~ tr/,/|/; print join "|",@F' ip.txt 
1,2|3,4|5|6|7|8
1,8|4|6,5,3|4|5
  • -F'\|' split input line on | and save to @F array
  • $F[-1] =~ tr/,/|/; for last element of array, replace all , with |
  • print join "|",@F print the modified @F array with | as separator

And for some regex magic:

$ perl -pe 's/.*\|(*SKIP)(*F)|,/|/g' ip.txt
1,2|3,4|5|6|7|8
1,8|4|6,5,3|4|5
  • .*\|(*SKIP)(*F) skip the pattern until last |
  • then replace all , with |

Upvotes: 1

heemayl
heemayl

Reputation: 42017

With awk:

awk 'BEGIN{FS=OFS="|"} gsub(",", "|", $NF)'
  • BEGIN{FS=OFS="|"} sets both the input and output field delimiter as literal |

  • gsub(",", "|", $NF) substitute all (gsub()) ,s with | in the last field ($NF)

Example:

$ awk 'BEGIN{FS=OFS="|"} gsub(",", "|", $NF)' <<<'1,2|3,4|5|6,7,8'
1,2|3,4|5|6|7|8

$ awk 'BEGIN{FS=OFS="|"} gsub(",", "|", $NF)' <<<'1,8|4|6,5,3|4,5'
1,8|4|6,5,3|4|5

Upvotes: 4

Related Questions