0

操作が必要な大きなデータベース ファイルがあります。基本的に、「|」で区切られた重複フィールドを避ける必要があります 為に:

-- TITLE1 | TITLE2   |T3   |TITLE4|TITLE5 
----------|----------|-----|------|---------------
--
DATA1   | SAME     |     |      |  blah blah
ELIGIBLE  | x1 
DATA1   | SAME     |     | blah |  blah
ELIGIBLE  | x2 
DATA1   | SAME     |     | blah |  blah blah
ELIGIBLE  | x2 
DATA2   | SAME     |     |      |  blah blah
ELIGIBLE  | y1 
DATA2   | SAME     |     | blah |  blah
ELIGIBLE  | y2
DATA2   | SAME     |     | blah |  blah blah blah blah
ELIGIBLE  | y2
DATA3   | SAME     |     |      |  blah blah
ELIGIBLE  | z1
DATA3   | SAME     |     | blah |  blah
ELIGIBLE  | z2
DATA3   | SAME     |     | blah |  blah blah blah blah
ELIGIBLE  | z2

私が使用しているコードは

BEGIN{ FS = "|" }
{
count[$1]++;
if (count[$1] == 1)
first [$1] = $0;
if (count[$1] > 1)
print first[$1]
NR==1;
}

しかし、それは私に出力を与えます:

-- TITLE1 | TITLE2   |T3   |TITLE4|TITLE5 
----------|----------|-----|------|---------------
--
DATA1   | SAME     |     |      |  blah blah
ELIGIBLE  | x1 
DATA2   | SAME     |     |      |  blah blah
DATA3   | SAME     |     |      |  blah blah

私は次のような出力を好むでしょう:

-- TITLE1 | TITLE2   |T3   |TITLE4|TITLE5 
----------|----------|-----|------|---------------
--
DATA1   | SAME     |     |      |  blah blah
ELIGIBLE  | x1 
DATA2   | SAME     |     |      |  blah blah
ELIGIBLE  | y1 
DATA3   | SAME     |     |      |  blah blah
ELIGIBLE  | z1 

表題欄はあまり気にしませんが、データを概説したとおりに表示する必要があります。素人の説明で申し訳ありませんが、解決策を教えていただければ幸いです。Linuxコマンドラインスクリプトに関しては初心者なので、私の答えが間違っている理由を誰かが説明できれば幸いです。私は awk に限定されず、任意のコマンド ソリューションを使用できます。awkで解決策を試したかっただけです。

4

2 に答える 2

0

この行は、指定された例で機能します。(データは並べ替えられており、oneline データ、oneline 適格です...) 形式が変更された場合、実際のデータで機能する保証はありません。自分でテストする必要があります。

タイトル/ヘッダーはスキップされます。

awk -F'|' '!(NR%2){next}$1 in a{next}{print;a[$1];getline;print}' file

それを試してみてください:

kent$  awk -F'|' '!(NR%2){next}$1 in a{next}{print;a[$1];getline;print}' file
DATA1   | SAME     |     |      |  blah blah
ELIGIBLE  | x1 
DATA2   | SAME     |     |      |  blah blah
ELIGIBLE  | y1 
DATA3   | SAME     |     |      |  blah blah
ELIGIBLE  | z1
于 2013-05-14T15:39:52.460 に答える
0

これを試すことができます:

awk -F\| '(printed!=0 && /ELIGIBLE/) {print; printed=0;} (!seen[$1] && $1 !~ /ELIGIBLE/) { print; printed = 1; seen[$1] = 1;  }' 

ほぼ確実に良い方法がありますが。

ETA:ここには優れた Awk チュートリアルがあり、Web には他にもいくつかのチュートリアルがあり、いくつかの優れた書籍もあります。ただし、基本的に awk プログラムは、パターンに一致するすべてのレコード (デフォルトでは行) で実行される一連のパターンとコード ブロックです。

awk '/foo/          { do this for lines that contain "foo" anywhere }
     ($1 == "bar")  { do this for lines whose first field is exactly "bar' }
     ($NF ~ /baz/)  { do this for lines whose last field contains "baz" }
     (NF == 1)      { do this for lines with exactly one field }
     (NR == 10)     { do this only on the 10th line }'

パターンがない場合、ブロックはすべての行で実行されます。

awk '{print $NF}'   # print the last field of every line

ブロックがなくパターンのみの場合、一致する行は変更されずに出力されます。

awk '/foo/'      # same as grep foo

入力が処理される前に、BEGIN というラベルの付いたブロックが実行されます。すべての入力が処理された後、END というラベルの付いたブロックが実行されます。

awk 'BEGIN { t = 0 } {t += $NF} END { print t }'   # print total of last column 

ただし、実際には初期化されていない変数は算術では 0 として扱われるため、初期化をスキップできます。

awk '{t += $NF} END {print t}'

一部のバージョンの awk では、;パターン/ブロックのペアの間にセミコロンまたは改行が必要です

于 2013-05-14T15:16:09.533 に答える