4
Staphylococcus_sp_HMSC14C01-KV792037.1:0.00371647154267842634,Staphylococcus_hominis_VCU122-AHLD01000058.1:0.00124439639436691308)69:0.00227646100249620856,(Staphylococcus_sp_HMSC072E01-KV814990.1:0.00288325234399461859,(((Staphylococcus_hominis_793_SHAE-JUSR01000051.1:0.00594391769091206796,Staphylococcus_pettenkoferi_1286_SHAE-JVVL01000037.1:0.00594050248317441135)

the comma is separating different items and in each item I want to remove everything between - and : including - but keeping : HOw can I do that? so it should look like

Staphylococcus_sp_HMSC14C01:0.00371647154267842634,Staphylococcus_hominis_VCU122:0.00124439639436691308)69:0.00227646100249620856

I used sed 's/-.*://' 1.file > 2.file but ended up removing the whole file and just kept the first and last values.

  • 1
    It looks like your input is a single line, and sed operates a line at a time. Since your regular expression allows for matching .*, the longest (greedy) match is from the first - to the last :. That's why it's deleting everything. You could try replacing the .* with [^,]*, which will force it to stop at the comma between items. – Dave M. Sep 29 '17 at 20:51
6

.* is a greedy regexp, matching the longest possible match. You need to match the shortest match but match it globally on the whole line. Try

sed 's/-[^:-]*:/:/g' 1.file > 2.file

The character class [^:-] matches anything except colon and dash (and maybe it should match anything except colon only), so the regexp says "dash followed by any number of non-dash, non-colon characters followed by a colon". It then replaces that with a colon (since you wanted to keep that) and does the replacement globally (the trailing g) on the line. If you omit the g, only the first instance would be replaced.

  • Thanks Nick, I still do not understand why cannot we say directly sed 's/-*:/:/g' why do we need [^:-]? – Ahmed Magdy Moustafa Sep 29 '17 at 21:26
  • .* will match the longest sequence of characters possible (that's why it's termed "greedy"). So /-.*:/ says "dash followed by any number of characters followed by colon": that matches the first dash and the last colon in your line (and everything in between) because that's longer than any other match. Is that clear? – NickD Sep 29 '17 at 21:30
4

Awk solution:

awk -F',' '{ for(i=1;i<=NF;i++) sub(/-[^:-]+/,"",$i) }1' OFS=',' 1.file

  • -F',' - field separator

  • for(i=1;i<=NF;i++) - iterating through all fields of the record

  • sub(/-[^:-]+/,"",$i - substitute the needed sequence (between - and : including - but keeping :)


The output:

Staphylococcus_sp_HMSC14C01:0.00371647154267842634,Staphylococcus_hominis_VCU122:0.00124439639436691308)69:0.00227646100249620856,(Staphylococcus_sp_HMSC072E01:0.00288325234399461859,(((Staphylococcus_hominis_793_SHAE:0.00594391769091206796,Staphylococcus_pettenkoferi_1286_SHAE:0.00594050248317441135)

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.