0

separated text file file1.dat with below content. I wanted to change the 3rd column by appending $COL to each of the #-separated text strings in that column.

I would like to to this for each line and save the file with same name.

Can someone help on this?

Sample input

name|class|colors|age|email
abc|xyz|#orange#green#pink#blue|16|[email protected]
pqr|xyz|#orange#green#pink#blue|20|[email protected]

Desired output

name|class|colors|age|email
abc|xyz|#orange$COL#green$COL#pink$COL#blue$COL|16|[email protected]
pqr|xyz|#orange$COL#green$COL#pink$COL#blue$COL|20|[email protected]
1
  • 1
    Welcome to the site. Would you mind editing your post to explain what you already tried, and where you ran into problems? Could you also indicate what OS flavor and version you are using, as that will give information on what tools (in which versions) are at your disposal. Will any tool be ok, or just awk and sed? Dou you want to include the literal string $COL or is this a shell variable whose content you want to insert?
    – AdminBee
    Commented May 8, 2020 at 8:09

1 Answer 1

1

In your example, you want to add $COL to the end of every string on the line that starts with #. For this simple case, you can simply do:

$ sed -E 's/(#[^#|]*)/\1$COL/g' file
name|class|colors|age|email
abc|xyz|#orange$COL#green$COL#pink$COL#blue$COL|16|[email protected]
pqr|xyz|#orange$COL#green$COL#pink$COL#blue$COL|20|[email protected]

Or, if your sed doesn't support -E:

sed 's/\(#[^#|]*\)/\1$COL/g' file

And you can use -i to edit the file in place:

sed -i -E 's/(#[^#|]*)/\1$COL/g' file

For the more general case, to replace add $COL to #-separated strings but only on the 3rd |-separated field, you can do:

$ awk -F'|' -vOFS='|' 'NR>1{gsub(/#[^#|]*/,"&$COL",$3)}1' file 
name|class|colors|age|email
abc|xyz|#orange$COL#green$COL#pink$COL#blue$COL|16|[email protected]
pqr|xyz|#orange$COL#green$COL#pink$COL#blue$COL|20|[email protected]

With newer versions of GNU awk, you can use -i inplace to edit the file in place:

awk -iinplace -F'|' -vOFS='|' 'NR>1{gsub(/#[^#|]*/,"&$COL",$3)}1'

Finally, just for fun, you can also use Perl to change all #-defiend strings:

perl -pe 's/(#[^#|]+)/$1\$COL/g' file 

or, to only do it on the 3rd column:

perl -F'\|' -lane '$F[2]=~s/(#[^#|]+)/$1\$COL/g; print join "|",@F' file 

or, to only do it on the 3rd column and skip the 1st line:

perl -F'\|' -lane '$F[2]=~s/(#[^#|]+)/$1\$COL/g if $.>1; print join "|",@F' file 

In both cases, you can use -i to edit the file in place.

2
  • this is working but putting control M characters along with in the header sed -i -E 's/(#[^#|]*)/\1$COL/g' file below one with awk is working perfectly as wanted to edit 3rd column only, but since GNU is not available i am not able to do inplace edit with awk awk -F'|' -vOFS='|' 'NR>1{gsub(/#[^#|]*/,"&$COL",$3)}1' file Commented May 8, 2020 at 9:42
  • 1
    @ashishgoyal this wouldn't add ^M. It sounds like your file was edited on Windows and has windows line endings. Does it work as expected if you first run dos2unix file and then the commands I gave?
    – terdon
    Commented May 8, 2020 at 9:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .