perl one-liner to keep only desired lines

匿名 (未验证) 提交于 2019-12-03 09:52:54

问题:

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

回答1:

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



回答2:

This way:

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


回答3:

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.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!