0

This is an extension of my previous question (Printing pattern of "C" character).

I would like to print "C" character from "text" column given in file.csv. The file.csv has two coloumns as ID and text.

I need to edit the distances in between as well as starting of the character such as following

So when in Column "text", printing the distance between two C characters such as, if "text" column has value DCFRCGHCCRF then it should print in the third column 1C2C2CC2

example input

c32_g1_i1_3,SCIPKHEECTNDKHNCCRKGLFKLKCQCSTFDDESGQPTERCACGRPMGHQAIETGLNIFRGLFKGKKKNKKTKG
c32_g1_i1_6,ACAERKKKCTKDDDCSCCGKWDKCSCNWPGREGCFCMRGMMATRLWKMAKC

Example output

c32_g1_i1_3,SCIPKHEECTNDKHNCCRKGLFKLKCQCSTFDDESGQPTERCACGRPMGHQAIETGLNIFRGLFKGKKKNKKTKG,1c6c6cc8c1c13c1c31
c32_g1_i1_6,ACAERKKKCTKDDDCSCCGKWDKCSCNWPGREGCFCMRGMMATRLWKMAKC,1c6c5c1cc5c1c7c1c14c0
1

How about something like this

perl -F, -alne '
  my @a = split "C", @F[1]; 
  my @b = (map { $_ ? length $_ : "" } @a); 
  print join ",", (@F, join "c", @b)
' file.csv 
c32_g1_i1_3,SCIPKHEECTNDKHNCCRKGLFKLKCQCSTFDDESGQPTERCACGRPMGHQAIETGLNIFRGLFKGKKKNKKTKG,1c6c6cc8c1c13c1c31
c32_g1_i1_6,ACAERKKKCTKDDDCSCCGKWDKCSCNWPGREGCFCMRGMMATRLWKMAKC,1c6c5c1cc5c1c7c1c14

Or more compactly

perl -F, -alne '
  print join ",", (@F, join "c", (map { $_ ? length $_ : "" } split "C", @F[1]))
' file.csv 

To get the desired behavior when there is a trailing C in the input, it is necessary to modify the split command with an explicit LIMIT parameter as noted - somewhat opaquely - in the split() perldoc :

Empty trailing fields, on the other hand, are produced when there is a match at the end of the string (and when LIMIT is given and is not 0), regardless of the length of the match.

So the expression becomes

$ perl -F, -alne '
  print join ",", (@F, join "c", (map { $_ ? length $_ : "" } split "C", @F[1], -1))
' file.csv
c32_g1_i1_3,SCIPKHEECTNDKHNCCRKGLFKLKCQCSTFDDESGQPTERCACGRPMGHQAIETGLNIFRGLFKGKKKNKKTKG,1c6c6cc8c1c13c1c31
c32_g1_i1_6,ACAERKKKCTKDDDCSCCGKWDKCSCNWPGREGCFCMRGMMATRLWKMAKC,1c6c5c1cc5c1c7c1c14c

(inspiration for the map taken from the quikest [sic] way to remove empty array elements)

  • Many thanks, this works perfectly fine, However would you please guide me on how to write this as perl program instead of one liner I would really appreciate it. – Trupti Apr 29 '16 at 12:41
  • @Trupti I'm not the best at "real" perl scripts - see if this helps How can I convert Perl one-liners into complete scripts? especially the -MO=Deparse trick – steeldriver Apr 29 '16 at 19:13
  • there is one issue with the code :( it does not print the last "C" example c51973_g1_i2_3,YIHFNSSQKCQCKGQSLLPVDCQQLLIVTNFVRSALCC,9c1c9c14 c54038_g1_i1_16,SCNTGCCNVDFPINKIFNKRGVASILGLIMVTKMQTMNILKCQCFVVIC,1c3cc34c1c4 – Trupti May 2 '16 at 16:19
  • @Trupti please see updated answer: the trick seems to be to add an explicit -1 limit parameter to the split – steeldriver May 13 '16 at 18:23

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.