J.Carter J.Carter - 1 month ago 8
Perl Question

perl one-liner to keep only desired lines

I have a text file (input.txt) like this:

NP_414685.4: 15-26, 131-138, 441-465
NP_418580.2: 493-500
NP_418780.2: 36-48, 44-66
NP_418345.2:
NP_418473.3: 1-19, 567-1093
NP_418398.2:


I want a perl one-liner that keeps only those lines in file where ":" is followed by number range (that means, here, the lines containing "NP_418345.2:" and "NP_418398.2:" get deleted). For this I have tried:

perl -ni -e "print unless /: \d/" -pi.bak input.txt del input.txt.bak


But it shows exactly same output as the input file.
What will be the exact pattern that I can match here?
Thanks

Answer

First, print unless means print if not -- opposite to what you want.

More to the point, it doesn't make sense using both -n and -p, and when you do -p overrides the other. While both of them open the file and set up the loop over lines, -p also prints $_ for every iteration. So with it you are reprinting every line. See perlrun.

Finally, you seem to be deleting the .bak file ... ? Then don't make it. Use just -i.

Altogether

perl -i -ne 'print if /:\s*\d+\s*-\s*\d+/' input.txt

If you do want to keep the backup file use -i.bak instead of -i


You can see the code equivalent to one-liner with particular options with B::Deparse (via O module)

Try: perl -MO=Deparse -ne 1 and perl -MO=Deparse -pe 1

Comments