1

ファイル1

A11;F1;BMW
A23;F2;BMW
B12;F3;BMW
H11;F4;JBW

ファイル2

P01;A1;0;0--00  ;123;456;150
P01;A11;0;0--00  ;123;444;208
P01;B12;0;0--00  ;123;111;36
P01;V11;0;0--00  ;123;787;33.9

出力

-;-;-;P01;A1;0;0--00  ;123;456;150
A11;F1;BMW;P01;A11;0;0--00  ;123;444;208
B12;F3;BMW;P01;B12;0;0--00  ;123;111;36
-;-;-;P01;V11;0;0--00  ;123;787;33.9

私は試した

awk 'FNR==NR {a[$2] = $0; next }{ if($1 in a) {p=$1;$1="";print a[p],$0}}' File1 File2 

しかし、うまくいきませんでした。

基本的には、FILE 1から詳細を取得し、FILE2(マスターリスト)と比較したいと思います。

例 :

FILE2のA1はFILE1で使用できなかったため、出力ファイルには最初の3つのフィールドに「-」があり、残りはFILE2にあります。これでA11ができ、FILE1で詳細を取得しました。したがって、ファイル1と2の両方からA11の詳細を記述します。

4

5 に答える 5

5

私は個人的にこれをPerlで行いますが、全員とその母親がPerlソリューションを提供しているので、次の方法があります。

各ファイルのレコードに一貫した数のフィールドがあり、各ファイルのレコードが辞書式順序で「結合」フィールドによってソートされている場合は、次を使用できますjoin

join -1 1 -2 2 -t ';' -e - -o '1.1 1.2 1.3 2.1 2.2 2.3 2.4 2.5 2.6 2.7' -a 2 File1 File2

オプションの説明:

  • -1 1そして-2 2、「結合」フィールド(A11A23など)がの最初のフィールドでFile1あり、の2番目のフィールドであることを意味しFile2ます。
  • -t ';'フィールドがで区切られていることを意味します;
  • -e -空のフィールドを次のように置き換える必要があることを意味します-
  • -o '1.1 1.2 1.3 2.1 2.2 2.3 2.4 2.5 2.6 2.7'これは、各出力行を、の最初の3つのフィールドとFile1、それに続く。の最初の7つのフィールドで構成することを意味しますFile2。(これが、このアプローチで各ファイルのレコードに一貫した数のフィールドが必要な理由です。)
  • -a 2File2からの対応する行がない場合でも、出力にからのすべての行を含めることを意味しますFile1。(それ以外の場合は、両方のファイルで一致する行のみが出力されます。)
于 2012-09-12T14:36:16.753 に答える
3

通常のPerlの方法:マスターリストを記憶するためにハッシュを使用します:

#!/usr/bin/perl
use warnings;
use strict;

my %hash;

open my $MASTER, '<', 'File1' or die $!;
while (<$MASTER>) {
    chomp;
    my @columns = split /;/;
    $hash{$columns[0]} = [@columns[1 .. $#columns]];
}
close $MASTER;

open my $DETAIL, '<', 'File2' or die $!;
while (<$DETAIL>) {
    my @columns = split /;/;
    if (exists $hash{$columns[1]}) {
        print join ';', $columns[1], @{ $hash{$columns[1]} }, q();
    } else {
        print '-;-;-;';
    }
    print;
}
close $DETAIL;
于 2012-09-12T14:33:05.753 に答える
2

Perlの場合:

use warnings;
use strict;
my %file1;
open (my $f1, "<", "file1") or die();
while (<$f1>) {
  chomp;
  my @v = (split(/;/))[0];
  $file1{$v[0]} = $_; 
}
close ($f1);
open (my $f2, "<", "file2") or die();
while (<$f2>) {
  chomp;
  my $v = (split(/;/))[1];
  if (defined $file1{$v}) {
    print "$file1{$v};$_\n";
  } else {
    print "-;-;-;$_\n";
  }
}
close ($f2);
于 2012-09-12T14:35:43.410 に答える
1

これは、2つの入力ファイルを読み取る必要があるため、1行のプログラムでは便利に実行できませんが、問題は難しくありません。

このプログラムは、からすべての行を読み取りfile1、最初のフィールドをキーとして使用して行をハッシュに格納します

次に、からのすべての行file2が読み取られ、2番目のフィールドがハッシュにアクセスするためのキーとして使用されます。//defined-or演算子は、要素の値が存在する場合は出力され、存在しない場合はデフォルトの文字列を出力するために使用されます。

最後に、からの現在の行file2が印刷されます

use strict;
use warnings;

my %data;

open my $fh, '<', 'file1' or die $!;
while (<$fh>) {
  chomp;
  my $key = (split /;/)[0];
  $data{$key} = $_;
}

open $fh, '<', 'file2' or die $!;
while (<$fh>) {
  my $key = (split /;/)[1];
  print $data{$key} // '-;-;-;', $_;
}

出力

-;-;-;P01;A1;0;0--00  ;123;456;150
A11;F1;BMWP01;A11;0;0--00  ;123;444;208
B12;F3;BMWP01;B12;0;0--00  ;123;111;36
-;-;-;P01;V11;0;0--00  ;123;787;33.9
于 2012-09-12T15:23:45.013 に答える
1

Perlソリューションには、非常に優れたモジュールText::CSVが含まれている場合があります。その場合は、値をハッシュに抽出し、後でそのハッシュを検索に使用できます。-;-;-;値をルックアップするときは、ルックアップハッシュの未定義の値に空白の値を挿入します。

use strict;
use warnings;
use Text::CSV;

my $lookup = "file1.csv";   # whatever file is used to look up fields 0-2
my $master = "file2.csv";   # the file controlling the printing

my $csv = Text::CSV->new({
        sep_char    => ";", 
        eol         => $/,  # to add newline to $csv->print()
        quote_space => 0,   # to avoid adding quotes 
    });

my %lookup;

open my $fh, "<", $lookup or die $!;

while (my $row = $csv->getline($fh)) {
    $lookup{$row->[0]} = $row;    # add entire row to specific key
}
open $fh, "<", $master or die $!; # new $fh needs no close

while (my $row = $csv->getline($fh)) {
    my $extra = $lookup{$row->[1]} // [ qw(- - -) ]; # blank row if undef
    unshift @$row, @$extra;       # add the new values
    $csv->print(*STDOUT, $row);   # then print them
}

出力:

-;-;-;P01;A1;0;0--00  ;123;456;150
A11;F1;BMW;P01;A11;0;0--00  ;123;444;208
B12;F3;BMW;P01;B12;0;0--00  ;123;111;36
-;-;-;P01;V11;0;0--00  ;123;787;33.9
于 2012-09-12T21:20:14.030 に答える