首页 > 解决方案 > 使用 perl 单行过滤文件列表

问题描述

我正在尝试使用 grep 的-P选项在命令行进行过滤,该选项应该使用 perl 的正则表达式

ls | grep -P ZZZZZTYT.vcf.gz作品

ls | grep -P ZZZZZTYT.vcf.gz$

不起作用。似乎锚点不适grep -P用于 GNU grep 3.4。

当然,这些例子是微不足道的。

我也试过用单线过滤,像 grep 这样的 la perl 单线?

ls | perl -ne 'print $1 if not $_ =~ m/\.gz$/'

但这也没有用。

ls | perl -ne 'print $1 if not /\.gz$/'

我的猜测是最好的选择是 perl one-liner。

如何将上述单行代码重写为 grep 文件列表?

标签: perlgrep

解决方案


尽管您的示例中有一些问题,但我无法重现您的问题。

对于命令ls | grep -P ZZZZZTYT.vcf.gz有效而ls | grep -P ZZZZZTYT.vcf.gz$无效,我的第一个猜测是您的文件末尾有空格或其他“不可见”字符。您可以尝试ls | cat -A(或cat -veT)查看实际上是否比您看到的更多。无论如何,您的正则表达式可以更好地用文字点 ( \.) 编写,因为.单独匹配任何内容。

在您的 perl onliners 中,您正在尝试打印$1并且此变量为空,来自perldoc perlvar

$<digits> ($1, $2, ...)
     Contains the subpattern from the corresponding set of capturing
     parentheses from the last successful pattern match, not counting
     patterns matched in nested blocks that have been exited already.

     These variables are read-only and dynamically-scoped.

     Mnemonic: like \digits.

我想你想要 print ,这个变量在你使用switch$_时保存当前行的内容(在perlvar和 perlfunc 中的引用)。比您可以将您的 perl oneliner 重写为:-n

ls | perl -ne'/\.gz$/ or print' # for not .gz files

或者

ls | perl -ne'/\.gz$/ and print' # list .gz files

$1使用您的示例,从网上删除就足够了。

如前所述,您需要检查文件名末尾是否有内容。

如果您的文件名和文件名中有“坏字符”,则此 oneliner 将用于列出 .gz 文件:

ls | perl -ne'/\.gz.*$/ and print'

推荐阅读