我有一个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");
}
答案 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 ' ', $_;
,其中' '
代表任意数量的空白(并且前导空格在拆分前已删除)
请提供确切的输入样本和所需的输出,以获取更完整的示例。