Reputation: 331
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
Upvotes: 2
Views: 309
Reputation: 66964
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 input file(s) 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 a one-liner with particular options with B::Deparse (via O module)
Try: perl -MO=Deparse -ne 1
and perl -MO=Deparse -pe 1
Upvotes: 6
Reputation: 1030
This:
perl -ne 'print if /:\s*(\d+\s*-\s*\d+\s*,?\s*)+\s*$/' input.txt
Prints:
NP_414685.4: 15-26, 131-138, 441-465
NP_418580.2: 493-500
NP_418780.2: 36-48, 44-66
NP_418473.3: 1-19, 567-1093
I'm not sure if you want to match lines that are possibly like this:
NP_418580.2: 493-500, asdf
or this:
NP_418580.2: asdf
This answer will not print these lines, if given to it.
Upvotes: 1
Reputation: 26131
This way:
perl -i.bak -ne 'print if /:\s+\d+-\d/' input.txt
Upvotes: 2