2016-08-16 5 views
-1

私はデータアラインメントに問題があります。以下の例では、前の行の終わりに属する行と、nullに変更する必要のある行があります。AWK複数レコードのフィールドの合計と、変数と等しい場合に結合

[email protected]@[email protected]@81 1/[email protected]/[email protected]/[email protected]/[email protected]@7.40 5w BITE SLOW 
[email protected]@[email protected]@41/[email protected]/[email protected]@[email protected]/[email protected] 4w BITE SLOW 
[email protected]@[email protected]@31/[email protected]/[email protected]/[email protected]/[email protected]/[email protected]* led 1/16p, BITE SLOW 
[email protected]@[email protected]@[email protected]/[email protected]@[email protected] 3/4 ins, BITE SLOW 
[email protected]@[email protected]@61/[email protected]/[email protected]/[email protected]/[email protected]@26.25 cut BITE SLOW 
[email protected]@[email protected]@[email protected]@81/[email protected]/[email protected]@13.10 5w BITE SLOW 
[email protected]@[email protected]@[email protected]/[email protected]@[email protected] 1/[email protected] 4w BITE FAST 
[email protected]@[email protected]@51/[email protected]@[email protected]/[email protected]@15.90 3w BITE FAST 
[email protected]@[email protected]@11/[email protected]/[email protected]/[email protected]@[email protected] in BITE FAST 
[email protected]@[email protected]@[email protected]@[email protected]@10 2 3/4 
19.50 6w upper, no response 
[email protected]@[email protected]@[email protected]@[email protected]@[email protected] off slow, no impact 

私がこれまで行ってきたことは、すべてのレコードの中で最も使用されたフィールド数を出力する変数を作成することです。私はawkでその変数を使用して、データが欠落しているか、間違って書式設定されている行を探したいとします。私は私が作業する必要がある行/レコードを見つけることができます

awk [email protected] -v x=$FLDCNT '{if(NF != x && [some code to check record and next record's combined field count = $FLDCNT]) [add the next row to the end of the current rows fields] print }' file 

が、私は「[]の手順をプリフォームする方法についてわからない午前:

FLDCNT=$(sed '/^ *$/d' file | sed 's/^ *//g' |awk [email protected] '{print NF}' | sort | uniq -c | sort |awk 'END{print $NF}'); 

の線に沿って何かを使用して"上記のコードのセクション。最後に

、出力は次のようになります。

[email protected]@[email protected]@81 1/[email protected]/[email protected]/[email protected]/[email protected]@7.40 5w BITE SLOW 
[email protected]@[email protected]@41/[email protected]/[email protected]@[email protected]/[email protected] 4w BITE SLOW 
[email protected]@[email protected]@31/[email protected]/[email protected]/[email protected]/[email protected]/[email protected]* led 1/16p, BITE SLOW 
[email protected]@[email protected]@[email protected]/[email protected]@[email protected] 3/4 ins, BITE [email protected] 
[email protected]@[email protected]@61/[email protected]/[email protected]/[email protected]/[email protected]@26.25 cut BITE SLOW 
[email protected]@[email protected]@[email protected]@81/[email protected]/[email protected]@13.10 5w BITE SLOW 
[email protected]@[email protected]@[email protected]/[email protected]@[email protected] 1/[email protected] 4w BITE FAST 
[email protected]@[email protected]@51/[email protected]@[email protected]/[email protected]@15.90 3w BITE FAST 
[email protected]@[email protected]@11/[email protected]/[email protected]/[email protected]@[email protected] in BITE FAST 
[email protected]@[email protected]@[email protected]@[email protected]@10 2 3/[email protected] 6w upper, no response 
[email protected]@[email protected]@[email protected]@[email protected]@[email protected] off slow, no impact 

私が知られているフィールド形式でif文を使用してのようないくつかのより容易な解決策があることの例から知っています。しかし、私は何千ものファイルを扱っており、フィールドとレコードの数はすべて異なっています。

要約すると、私はすべての行の最も一般的な列数を見つけようとしています、その共通数と一致しない行を見つけ、それらのoddballsを呼び出すことができ、oddballs奇妙なボールが共通の数字と同じ列カウントを持つようにし、そうであれば行を一緒に追加します。

+0

ありがとうございます、情報がnullになる行。その結果を反映するために質問を更新します。 –

+0

次に、それらは一緒に12のフィールドを持ち、それが共通のフィールドカウントでない場合、それは変数で宣言されます。そして、行の最後に 'NULL'を追加する必要があります。 –

答えて

1

あなたの質問にはperlというタグが付いています。だから、ここで読めるPerlのソリューションです:

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

my %count; 
my $max = 0; 

open my $FH, '<', shift or die $!; 
while (<$FH>) { 
    my $c = split /@/; 
    $count{$c}++; 
    $max = $c if $c > $max; 
} 

warn "The max count ($max) different from the most common\n" 
    if grep $_ > $count{$max}, values %count; 

seek $FH, 0, 0; 
my $leftover = 0; 
while (<$FH>) { 
    my $c = $leftover + split /@/; 
    if ($leftover) { 
     print '@'; 
     if ($c > $max) { 
      $c -= $leftover; 
      print "NULL\n"; 
     } 
    } 

    if ($c != $max) { 
     $leftover += $c; 
     chomp; 
    } else { 
     $leftover = 0; 
    } 
    print; 
} 
0

awkと前進可能な方法:

awk [email protected] ' 
    NF>=10 { 
     if(p!="") { 
     print p "@NULL" 
     p="" 
     } 
     print 
    } 
    NF<10 { 
     if(!p || p=="") { 
     p=$0 
     } else { 
     print p "@" $0;p="" 
     } 
    }' file 

このスクリプトは、10個の以上のフィールドを持つすべての行を出力します。両方のフィールドが10フィールド未満の場合は連続する行を連結し、9フィールドの場合は@NULLを追加します。

関連する問題