Perl:尝试查看X行的第N列是否匹配X-1行的第N列

时间:2018-07-31 23:31:03

标签: regex perl

我有一个perl脚本,该脚本逐行读取文本文件并将该行分成4个不同的列(由破折号表示,在代码中称为$ cols [0-3];重要部分以粗体显示)。对于第0列小数点之前的每个 值,它应随机生成十六进制颜色。

本质上,我需要比较当前行中的第X列与上一行中的第X列是否匹配。

A ---- last_column ---- 221 ---- 18

A ---- last_column ---- 221 ---- 76

A ---- last_column ---- 221 ---- 42

B ---- last_column ---- 335 ---- 18

C ---- last_column ---- 467 ---- 83

到目前为止,我正在为每行随机生成一个新的#random_hex_color,但所需的输出如下:

221 .18 ------- #EB23AE1 ------- @ $ some / random / path / A.txt ------- last_column

221 .76 ------- #EB23AE1 ------- @ $ some / random / path / A.txt ------- last_column

221 .42 ------- #EB23AE1 ------- @ $ some / random / path / A.txt ------- last_column

335 .18 ------- #AC16D6E ------- @ $ some / random / path / B.txt ------- last_column

467 .83 ------- #FD89A1C ------- @ $ some / random / path / C.txt ------- last_column

[输入文件和所需输出的图像] [1]

my @cols;
my $row;
my $color = color_gen();
my $path = "\t@\some_random_path/"; 
my $newvar = dir_contents();
my @array = ($color, $path, $newvar);
my %hash;

while ($row = <$fh>){
    next if $row =~ /^(#|\s|\t)/; #skip lines beginning with comments and spaces
    @cols = split(" ", $row);
    %hash = (
        "$cols[2]" => ["$color", "$path", "$newvar"]
         );
    say Dumper (\%hash);
    print("$cols[2].$cols[3]\t#");
    print(color_gen());
    printf("%-65s", $path.dir_contents());
    print("\t\t$cols[0]_"."$cols[1]"." 1 1\n");
}

1 个答案:

答案 0 :(得分:0)

使用散列来存储,从而能够检查第一列中的不同值。

我假设color_gen()在每次调用时都返回新的随机颜色。所需的输出对我来说还不清楚,因此仅在代码中指明。

use warnings;
use strict;

my $file = shift @ARGV;
die "Usage: $0 filename\n" if not $file or not -f $file;

open my $fh, '<', $file or die "Can't open $file: $!";

my %c0;

while (<$fh>) {
    next if /^(?:\s*$|\s*#)/;  # skip: spaces only or empty, comment
    my @cols = split;

    my ($num) = $cols[0] =~ /^([0-9]+)/;

    if (not exists $c0{$num}) {  # this number not seen yet; assign color
        $c0{$num} = color_gen();
    }

    # write line of output, with $c0{$num} and @cols
}

使用正则表达式作为该字符串中的前导数字来提取值“ 在第0列小数点之前”,并将其存储在$num中。需要使用括号来为match运算符提供列表上下文,在这种情况下,它将返回捕获的值。参见perlretut

此数字作为键存储在哈希中,其值是生成的颜色。除非它已经存在,否则将在这种情况下被看到并为其生成颜色。这样,您可以跟踪该列中的不同数字。然后,您可以使用$c0{$num}写输出。

这可以写得更紧凑,但我希望清楚。

这里跳过的行不是那些“ 以注释和空格开头的”,而是只有空格(或为空)或注释的行。如果您真的要跳过仅以空格(或#)开头的行,请确实使用/^(?:\s|#)/,其中?:使()仅分组而不捕获。

对代码的一些注释

  • 在每个程序的开头总是有use warnings;use strict;

  • 正则表达式中的\s与大多数类型的空格匹配;标签不需要单独的模式

  • 可以在while条件中声明一个变量,这使它的作用域非常完美-可以循环。但是,您也可以忽略它并使用$_

  • 如果while条件仅读取了输入,例如<$fh>,则将该值分配给$_ variable;另请参见I/O in perlop。 我在这里使用它,因为这样正则表达式更简单(默认情况下与$_匹配),split

  • 也是如此
  • 不带参数的split的默认值为split ' ', $_;,其中' '代表任意数量的空白(并且前导空格在拆分前已删除)

    < / li>

请提供确切的输入样本和所需的输出,以获取更完整的示例。