Perlソリューション:

Perlソリューション:

これは、処理するスクリプトを探したい2つの一般的な区切りテキストファイル変換の問題です(これに最もawk適しているかどうかはわかりません)。perl

csh私はSolaris 10 Unixサーバーのデフォルトシェルであるため、またはcshシェルと連携するソリューションがsh優先されます。

質問1:

File1.dat次の2つの区切り付きASCIIファイルがあります。File2.dat

File1.dat (マップファイル):

1|A  
2|B  
3|C  
4|D  
5|E  
6|F  
.  
.  
.  
26|Z  
27|Who  
28|What  
29|Where

ファイル2.dat

Field1|Field2|Field3  
1|John|20120101  
3|Amy|20120103  
6|Larry|20120104  
3|Kevin|20120203  
8|Fred|20120623  
4|Mary|20120728  
26|Eric|20120819  
28|Larry|20120917

File1.datに表示されているマップを使用して、次の3番目のFile2.datファイルに変換したいと思います。File3.datデフォルトでは、File1.datのマッピングを使用してファイルに新しい列を作成/入力し、最終的に新しく変換されたファイルには4つの列があります。

ファイル3.dat

Field1|Field2|Field3|Field4  
1|A|John|20120101  
3|C|Amy|20120103  
6|F|Larry|20120104  
3|C|Kevin|20120203  
8|H|Fred|20120623  
4|D|Mary|20120728  
26|Z|Eric|20120819  
28|What|Larry|20120917

質問2:

次の共通項目を含む一連のレコードのうち、最初のレコード(ソートされた一連のレコード)のみを保持したいと思います。 [フィールド2、フィールド3、フィールド4はレコード内の同じ値を持つ]

以下の初期区切りファイルFile1.datがあります(15レコード、各レコードには4つのフィールドがあります)。左側はファイルの一部ではなく、進行状況を追跡できるレコード#です。

ファイル1.dat

    Field1|Field2|Field3|Field4
1.    20120227|Andy|101|34  
2.    20120315|Andy|101|34  
3.    20120415|Andy|101|36  
4.    20120417|Andy|103|37  
5.    20120417|Andy|103|37  
6.    20120227|Jane|101|34  
7.    20120315|Jane|101|34  
8.    20120415|Jane|101|36  
9.    20120417|Jane|103|37  
10.   20120417|Jane|103|37  
11.   20120227|Bob|101|34  
12.   20120315|Bob|101|34  
13.   20120415|Bob|101|36  
14.   20120417|Bob|103|37  
15.   20120417|Bob|103|37

File1.dat15個のレコードを含むこのファイル()を以下のように新しいファイル()に変換したい(この9個のレコードのみを保持)。File2.dat

ご覧のとおり、重複File1.datレコードの定義が[Field2&Field3&Field4は2つ以上のレコードで同じ値を持つ]と同じ場合、重複レコードを削除します。

ファイル2.dat

1.   20120227|Andy|101|34
3.   20120415|Andy|101|36
4.   20120417|Andy|103|37
6.   20120227|Jane|101|34
8.   20120415|Jane|101|36
9.   20120417|Jane|103|37
11.  20120227|Bob|101|34
13.  20120415|Bob|101|36
14.  20120417|Bob|103|37

結論として:

ソリューションコードで、次の2つの問題が解決される場所を教えてください。

a)私のファイルの区切り文字はパイプ|文字です
。 b)コードのどの部分がField1、Field2、Field3、Field4などを参照していますか?

ベストアンサー1

Perlソリューション:

質問1.

File1.datはハッシュとして読み込まれ、最初の列はキーで、2番目の列は値です。その後、File2.datが処理され、ハッシュの値が最初の列(Perlの場合は列0)から取得されたキーに基づいて行の値を表す配列に挿入されます。

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

my %tab;

open my $F1, '<', 'File1.dat' or die $!;
while (<$F1>) {
    chomp;
    my ($key, $value) = split /\|/; # Here, the delimiter is mentioned.
    $tab{$key} = $value;
}

open my $F2, '<', 'File2.dat' or die $!;
while (<$F2>) {
    chomp;
    my @cols = split /\|/;
    splice @cols, 1, 0, $tab{$cols[0]};
    print join('|', @cols), "\n";
}

標準ユーティリティを使用して同様の出力を得ることができます。

join -a2 -t'|' <(sort File1.dat) <(sort File2.dat) | sort -n

質問2.

ハッシュですでに見たフィールドの組み合わせを覚えておいてください。新しい組み合わせであればその行を印刷し、そうでなければ何もしません。

#!/usr/bin/perl
use warnings;
use strict;
use feature 'say';

my %seen;
while (<>) {
    chomp;
    my @fields = split /\|/, $_, 2;          # Only split into 2 fields.
    say unless exists $seen{$fields[1]};     # Do not print if already seen.
    undef $seen{$fields[1]};                 # Mark the key as seen.
}

おすすめ記事