regex - Perl:无法从文件中获取正确的匹配项

标签 regex perl pattern-matching

我的脚本需要帮助。我正在编写一个脚本来检查用户名是否仍然存在于 /etc/passwd 中。我知道这可以在 BASH 上完成,但我想尽可能避免使用它,而只专注于使用 Perl 进行编写。

好的,所以我的问题是,我的脚本在我的 $password_file 中找不到正确的匹配项。即使它仍在文件中,我仍然收到 No root found 错误。

执行脚本。

jpd@skriv ~ $ grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
jpd@skriv ~ $ ~/Copy/documents/scripts/my_perl/test.pl root
Applying pattern match (m//) to @id will act on scalar(@id) at /home/jpd/Copy/documents/scripts/my_perl/test.pl line 16.
No root found!
jpd@skriv ~ $ 

另外,为什么我总是收到“正在应用模式匹配...”警告?

代码如下:

#!/usr/bin/perl

use strict;
use warnings;

my $stdin = $ARGV[0];
my $password_file = '/etc/passwd';

open (PWD, $password_file) || die "Error: $!\n";
    my @lines = (<PWD>);
close PWD;

for my $line (@lines) {
    my @list = split /:/, $line;
    my @id = "$list[0]\n";
    if (@id =~ m/$stdin/) {
        die "Match found!\n";
    } else {
        print "No $stdin found!\n";
        exit 0;
    }
}

提前致谢! :)

问候,
sedawkgrep
Perl 新手

最佳答案

关于您的代码,我有几点需要指出:

  • 使用 use strict; 做得很好和 use warnings; 。它们应该包含在每个 perl 脚本中。

  • 选择有意义的变量名称。

    $stdin 太通用了。 $username 可以更好地记录脚本的意图。

  • 关于您的文件处理:

    • 包括 use autodie;任何时候您处理文件时。

      这个编译指示会自动处理错误消息,并且会为您提供比仅仅“Error: $!\n”更好的信息。另外,如果您想要手动生成错误消息,请务必从消息中删除新行,否则 die 将不会报告行号。

    • 使用词法文件句柄和open的三个参数形式

      open my $fh, '<', $password_file;
      
    • 除非需要,否则不要将整个文件加载到内存中。相反,使用 while 循环并逐行处理文件

  • 关于您的比较:@id =~ m/$stdin/:

    • 始终在比较左侧使用标量=~

      comparison operator将标量绑定(bind)到模式。因此,@id =~ m/$stdin/ 行实际上是将 @id 的大小与您的模式进行比较:"1"=~ m/$stdin/。这显然是一个错误。

    • 请务必使用 quotemeta 对正则表达式特殊字符进行转义或\Q...\E:

      $list[0] =~ m/\Q$stdin/
      
    • 由于您实际上想要直接相等,因此根本不要使用正则表达式,而是使用 eq

  • 您仅在处理完文件的第一行后就退出。

    在一个 fork 中,如果你在第一行找到匹配项,你就会死掉。在您的另一个分支中,您退出时假设没有其他行会匹配。

通过这些更改,我会将您的脚本更正为以下内容:

#!/usr/bin/perl
use strict;
use warnings;
use autodie;

my $username = $ARGV[0];
my $password_file = '/etc/passwd';

open my $fh, '<', $password_file;

while (<$fh>) {
    chomp;
    my @cols = split /:/;
    if ($cols[0] eq $username) {
        die "Match found!\n";
    }
}

print "No $username found!\n";

关于regex - Perl:无法从文件中获取正确的匹配项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25230694/

相关文章:

c++ - 正则表达式与字符串 :find() for simple word boundary

java - 使用正则表达式匹配除 = 之外的任何字符

pattern-matching - 在 Coq 的单个子句中模式匹配多个构造函数

scala - 检查集合中包含的所有元组中给定的整数元素是否按连续顺序排列

Java:使用正则表达式计算字符串中的数字

linux - 收到时邮件格式更改

从数据文件读取输入数据时,Perl WWW::Mechanize 不打印结果

perl - Dancer 插件加载模板

java - 如何在 Java 中声明匹配模式?

regex - 正则表达式匹配确切数量的字符?