【问题标题】:Perl: Trying to see if the Nth column of line X matches the Nth column of line X-1Perl:试图查看第 X 行的第 N 列是否与第 X-1 行的第 N 列匹配
【发布时间】:2019-01-08 10:39:37
【问题描述】:

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

本质上,我需要比较当前行中的第 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");
}

【问题讨论】:

  • 欢迎来到 Stack Overflow,Cori!如果您有时间,请访问我们的help centertour

标签: regex perl


【解决方案1】:

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

我假设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 中。需要使用括号来为匹配运算符提供列表上下文,在这种情况下,它会返回捕获的值。见perlretut

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

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

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

代码上的几个cmets

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

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

  • 可以在while 条件中声明一个变量,这使得它的作用域完美——到那个循环。但是,您也可以省略它并使用$_

  • 如果while条件只有输入读,如&lt;$fh&gt;,则赋值给$_ variable;另见I/O in perlop。 从那以后我在这里使用它,正则表达式更简单(默认匹配$_),split

  • 不带参数的split 的默认值为split ' ', $_;,其中' ' 代表任意数量的任意空格(在拆分前会删除前导空格)

请提供输入和所需输出的准确示例以获得更完整的示例。

【讨论】:

  • 有了你的建议和一些玩弄,我已经开始工作了。感谢您的帮助!
  • @CoriGrainger 太好了 :) 如果有任何问题,请告诉我。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-15
  • 2014-02-28
  • 2019-04-12
相关资源
最近更新 更多