- 締切済み
重複レコードのチェックができなくて困っています。
UNIX / Cシェル ファイルが以下の条件のときにエラーとなるようにしたいのですが、どのような処理にすればよいかわかりません。 ファイルは各項目固定長(1つ目5バイト、2つ目6バイト、3つ目7バイト) AAAAABBBBBBDDDDDDD・・・(1) AAAAABBBBBBCCCCCCC・・・(2) EEEEEFFFFFFGGGGGGG・・・(3) EEEEEHHHHHHJJJJJJJ・・・(4) KKKKKLLLLLLMMMMMMM・・・(5) (1)と(2)のように頭2つの項目((1)でいえばAAAAAとBBBBBB)が一致している場合はエラーではないが、(3)と(4)のように頭1つの項目は一致しているが、2つ目の項目が違うものはエラーとなるように処理。 (5)のように1つ目の項目が一致するものがなければエラーではない。 初めての質問のため至らない点もあるかと思いますが、よろしくお願いします。
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- sakusaker7
- ベストアンサー率62% (800/1280)
最近のUnixでPerlが入ってない(最新版かどうかはともかく)ってのは 商用でもあまり考えられないような気がするんですがそれはさておき。 awkだとこんな感じですか。 なおちょっと考えれば分かることですが、処理対象のファイルが でかくなるにつれて加速度的に処理時間が延びていきます。 #!/usr/bin/awk -f { idx = FNR split("", f); f[1] = substr($0, 1, 5); f[2] = substr($0, 6, 6); f[3] = substr($0, 13, 7); f1[idx] = f[1]; f12[idx] = f[1] f[2]; for (i=1; i<idx; i++) { if (f[1] == f1[i] && (f[1] f[2]) != f12[i]) printf "dupulicate record is at %d: %s\n", FNR, $0 > "/dev/stderr"; } }
- sakusaker7
- ベストアンサー率62% (800/1280)
元ファイルの大きさによってはいろいろ改良の余地があると思いますが とりあえずの例で #!/usr/bin/perl use strict; use warnings; use feature ':5.10'; my $template = 'A5 A6 A7'; my @records; while (my $line = <DATA>) { chomp $line; my @fields = unpack $template, $line; foreach my $item_ref (@records) { say "duplicate record is at $. '$line'" if ($fields[0] eq $item_ref->[0] && $fields[1] ne $item_ref->[1]); } push @records, [@fields]; } __END__ AAAAABBBBBBDDDDDDD AAAAABBBBBBCCCCCCC EEEEEFFFFFFGGGGGGG EEEEEHHHHHHJJJJJJJ KKKKKLLLLLLMMMMMMM 実行結果: duplicate record is at 4 'EEEEEHHHHHHJJJJJJJ'
- sakusaker7
- ベストアンサー率62% (800/1280)
ああ、すみません。 全体で重複があるかどうかチェック、ですね。
- sakusaker7
- ベストアンサー率62% (800/1280)
何と何を比較するのでしょうか? 一つのファイルの1行目と2行目、2行目と3行目…とか? それから >Cシェル Perl/Ruby/gawk を使うのはあり? なし?
補足
sakusaker7さん 回答ありがとうございます。 説明が足らず申し訳ございません。 Perl、Rubyは環境として使えないです。awkは使えますがgawkが使えたかはわかりません。 できれば、UNIXのコマンドなどを使ってできる方法を探しています。