3

I would like to get >chr05_pilon_pilon.12.1 but unfortunately the below command does not remove the t

echo '>chr05_pilon_pilon.12.t1' | sed '/^\\>chr[0-9][0-9]_pilon_pilon/ s/\(.*\)t/\1/g'
>chr05_pilon_pilon.12.t1

What did I miss?

0
6

Whenever you work with regular expressions, you should remember that "less is more". I mean you should always try to use the simplest and shortest pattern that matches your data. Don't try to match everything, only go for the part you actually need.

In this case, you have >chr05_pilon_pilon.12.t1 and all you want to do is remove the last t after the last .. So don't try to match from the beginning, you don't care about that and it will only make your regular expression more complicated and easier to get wrong, as you did. Here are a few alternatives, depending on what you actually need:

  1. Remove all non-numerical characters after the last . on lines starting with >:

     $ echo '>chr05_pilon_pilon.12.t1' | sed -E 's/^(>.*)\.[^0-9]*/\1./'
     >chr05_pilon_pilon.12.1
    
  2. Remove the last t on lines starting with >:

     $ echo '>chr05_pilon_pilon.12.t1' | sed -E 's/^(>.*)t/\1/'
     >chr05_pilon_pilon.12.1
    
  3. As above, but only if the t is immediately after a .

     $ echo '>chr05_pilon_pilon.12.t1' | sed -E 's/^(>.*\.)t/\1/'
     >chr05_pilon_pilon.12.1
    
  4. Remove the last t that comes after a . but only on lines starting with > then chr followed by exactly two numbers and pilon_pilon:

     $ echo '>chr05_pilon_pilon.12.t1' | sed -E 's/^(>chr[0-9][0-9]_pilon_pilon.*\.)t/\1/'
     >chr05_pilon_pilon.12.1
    
  5. Finally, assuming you might also have X, Y and M or MT chromosomes, you might want to extend the above to match on those as well

     $ printf '>chrX_pilon_pilon.12.t1\n>chr05_pilon_pilon.12.t1\n>chrMT_pilon_pilon.12.t1\n' |
          sed -E 's/^(>chr([0-9XYM]{1,2}|MT)_pilon_pilon.*\.)t/\1/'
     >chrX_pilon_pilon.12.1
     >chr05_pilon_pilon.12.1
     >chrMT_pilon_pilon.12.1
    
6

Your pattern tries to match a \ at the start of the line, which you don't have:

$ echo '>chr05_pilon_pilon.12.t1' | sed '/^\\>chr[0-9][0-9]_pilon_pilon/ s/\(.*\)t/\1/'
>chr05_pilon_pilon.12.t1

Without trying to match the \ at the start of the line:

$ echo '>chr05_pilon_pilon.12.t1' | sed '/^>chr[0-9][0-9]_pilon_pilon/ s/\(.*\)t/\1/'
>chr05_pilon_pilon.12.1

You may possibly also want to allow for the X, Y, and possibly M chromosomes (depending on what your genome assembly contains):

echo '>chr05_pilon_pilon.12.t1' | sed -E '/^>chr([0-9][0-9]|[XYM])_pilon_pilon/ s/(.*)t/\1/'

Note too that /g is not needed.

-1

This below command will help you to get the desired output

#!/bin/bash
echo '>chr05_pilon_pilon.12.t1' | sed 's/.t/./'

Output :

 >chr05_pilon_pilon.12.1
8
  • That regular expression looks a little too enthusiastic; try echo hot | sed s/.t/./. – marcelm Nov 22 '20 at 22:36
  • Did you mean \.t? – Toby Speight Nov 23 '20 at 13:25
  • @TobySpeight re - read the requirement , it clearly specifics need to remove t – codeholic24 Nov 23 '20 at 14:18
  • @marcelm re -read the requirement , it clearly specifics need to remove t – codeholic24 Nov 23 '20 at 14:20
  • @codeholic24 Yes, but your regular expression pays no attention to the input structure; it'll remove the first t that's not the first character. I feel that's not robust enough. And if you really want to go that route, why not simply s/t//? – marcelm Nov 23 '20 at 14:38

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.