我有一个 csv 文件,其中包含一堆从 500 到 500,000 的数字,并且希望通过将不匹配的内容向右移动,同时将其余列向右移动,但保持顶行不变,然后将匹配项替换为 1 并替换不匹配项用 0 替换该列中的空格,这样我就有了定长矩阵,例如,我有以下内容:
12345,6457,789,21231,657
6457,21231,657
12345,789,21231
当我在第一列中搜索字符串 12345 时,将第二行向右推后,将匹配的单元格(第 1 行第 1 列和第 3 行第 1 列)替换为 1,将不匹配的单元格(第 2 行第 1 列)替换为 0 和逗号..见下文:
1,6457,789,21231,657
0,6457,21231,657
1,789,21231
现在,当我在第二列中搜索下一个字符串(6457)时,执行与上面相同的步骤,即用 1 替换匹配的单元格(第 1 行第 2 列和第 2 行第 2 列)和不匹配的单元格(第 3 行第 2 列) ) 将第三行向右推后带有 0 和逗号..见下文:
1,1,789,21231,657
0,1,21231,657
1,0,789,21231
依此类推,直到得到所需的输出,如下所示:
1,1,1,1,1
0,1,0,1,1
1,0,1,1,0,
下面是示例文件的链接。
谢谢
答案1
这个 Perl 脚本将执行您想要的操作:
#!/usr/bin/perl
## Read the file's lines into the @lines aray.
my @lines = <>;
## read the values from the first line and save them as @values
my @values = split(/,/, $lines[0]);
## Iterate over the values. $#values is the number of elements
## in the array.
for my $i (0..$#values){
## Remove trailing newlines and save this value as $value
chomp(my $value = $values[$i]);
## Iterate over each line
for my $k (0..$#lines ) {
## remove trailing newlines.
chomp($lines[$k]);
## Get this line's values
my @lineValues = split(/,/, $lines[$k]);
## If the value at position $i on this line is the same
## as the value at position $i of the first line.
if ($lineValues[$i] == $value) {
## Set this value to 1
$lineValues[$i] = 1
}
## If they are not equal
else {
## Prepend '0,' to this line's value
$lineValues[$i] = '0,' . $lineValues[$i];
}
## Save the modified line back in the @lines array
$lines[$k] = join ',', @lineValues;
}
}
## Print the final output
print join "\n", @lines;
print "\n";
将其另存为foo.pl
并像这样运行(如果在问题的示例文件上运行则显示输出):
$ perl foo.pl foo.csv
1,1,1,1,1
0,1,0,1,1
1,0,1,1,0,
在您链接到的文件上:
$ perl foo.pl file.csv
1,1,1,1,1,1
1,0,1,0,1,1
0,1,0,1,1,1
0,0,1,1,1,1
0,1,1,1,1,1
1,1,1,0,0,1
0,1,1,1,0,1