一致する行と一致しない行の列を見つけ、文字に置き換えます。

一致する行と一致しない行の列を見つけ、文字に置き換えます。

私は500から500,000までの数字を含むcsvファイルを持っており、一致を1に置き換え、一致しない項目をその列の空白に0に置き換えたいと思います。固定長行列たとえば、次のようなものがあります。

12345,6457,789,21231,657
6457,21231,657
12345,789,21231

最初の列で文字列12345を検索すると、2番目の行を右にスライドさせ、一致するセル(行1、列1、行3、列1)を​​1に置き換え、一致しないセル(行2、列1)を​​置き換えます。 )は0とカンマで置き換えられます。下記をご覧ください。

1,6457,789,21231,657
0,6457,21231,657
1,789,21231

2番目の列で次の文字列(6457)を検索するときは、上記と同じ手順を実行します。つまり、一致するセル(行1、列2、行2、列2)を1と一致しないセル(行3)に置き換えます。 、列2))3番目の行を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,

以下はサンプルファイルのリンクです。

https://pastebin.com/AmbHYC9T

ありがとう

ベストアンサー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

おすすめ記事