Reputation: 23
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
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 separatorAnd 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 |
,
with |
Upvotes: 1
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