1

次の形式のテキスト ファイルがあります。

211B1 CUSTOMER|UPDATE|  
211B2 CUSTOMER|UPDATE|  
211B3 CUSTOMER|UPDATE|  
211B4 CUSTOMER|UPDATE|  
211B5 CUSTOMER|UPDATE|  
567FR CUSTOMER|DELETE|  
647GI CUSTOMER|DELETE|  

テキスト ファイルを処理し、次のように報告するスクリプトが必要です。

  • Acct の列 CUSTOMER の「UPDATE」が見つかりました: 211B1、211B2、211B3、211B4、211B5
  • 列 CUSTOMER の "DELETE" が Acct で見つかった: 5675FR、6470GI

簡単な解決策をスクリプト化することはできますが、これは少し複雑に思えます。支援やガイダンスをいただければ幸いです。

4

5 に答える 5

6

collat​​e.pl

#!/usr/bin/perl

use strict;

my %actions;
while (<>) {
    my ($key, $fld, $action) = /^(\w+) (.+?)\|(.+?)\|/ or die "Failed on line $.!";
    push @{$actions{$action}{$fld}}, $key;
}

foreach my $action (keys %actions) {
    foreach my $fld (keys %{$actions{$action}}) {
        print "\"$action\" for column $fld found for Acct's: " . join(",", @{$actions{$action}{$fld}}), "\n";
    }
}

次のように使用します。

perl collate.pl < input.txt > output.txt
于 2009-05-05T12:58:27.197 に答える
1

awk を使用:

echo '211B1 CUSTOMER|UPDATE|  
211B2 CUSTOMER|UPDATE|  
211B3 CUSTOMER|UPDATE|  
211B4 CUSTOMER|UPDATE|  
211B5 CUSTOMER|UPDATE|  
567FR CUSTOMER|DELETE|  
647GI CUSTOMER|DELETE|' | awk -F '[ |]' '
    BEGIN {
        upd="";del=""
    } {
      if ($3 == "UPDATE") {upd = upd" "$1};
      if ($3 == "DELETE") {del = del" "$1};
    } END {
        print "Updates:"upd; print "Deletes:"del
    }'

生成:

Updates: 211B1 211B2 211B3 211B4 211B5
Deletes: 567FR 647GI

基本的には、各行を 3 つのフィールド (-Fオプションを使用) に分割し、「コマンド」に応じて、追加する更新と削除のリストを維持します。

BEGINandはすべての行処理のEND前後に実行されるため、初期化と最終出力になります。

簡単にするためにスクリプトに入れます。コマンド ライン ツールとして残したのは、それが通常 awk スクリプトをデバッグする方法だからです。

于 2009-05-05T13:01:05.537 に答える
1
#!/usr/bin/perl

use strict;
use warnings;

my %data;

while ( my $line = <DATA> ) {
    next unless $line =~ /\S/;
    my ($acct, $col, $action) = split /\s|\|/, $line;
    push @{ $data{$action}->{$col} }, $acct;
}

for my $action ( keys %data ) {
    for my $col ( keys %{ $data{$action} } ) {
        print qq{"$action" for column $col found for acct's: },
              join q{,}, @{ $data{$action}->{$col} }, "\n";    
    }

}
__DATA__
211B1 CUSTOMER|UPDATE|  
211B2 CUSTOMER|UPDATE|  
211B3 CUSTOMER|UPDATE|  
211B4 CUSTOMER|UPDATE|  
211B5 CUSTOMER|UPDATE|  
567FR CUSTOMER|DELETE|  
647GI CUSTOMER|DELETE|
于 2009-05-05T13:04:59.193 に答える
0

別の awk バージョン。ただし、コード値の順序が逆で、各行の終わりに余分な「,」があります。


BEGIN { FS="[ |]" }

{
        key = $3 " for column " $2
        MAP[ key ] = $1 "," MAP[ key ]
}

END {
        for ( item in MAP ) {
                print item " found for Acct's: " MAP[ item ]
        }
}
于 2009-05-11T22:13:42.903 に答える
-2

あなたの質問に基づいて、これを行うことができます:

perl -i.bak -pe'if(/^211B[1-5]/){s/CUSTOMER/UPDATE/}elsif(/^(5675FR|6470GI)/){s/CUSTOMER/DELETE/}' filename

この例では、最後の 2 つの口座番号が異なり、2 番目の列には既にそれらの値が含まれていることに気付きましたが...

于 2009-05-05T12:59:51.217 に答える