2010-12-02 6 views
1

次の4つのフィールドを持つファイルがあります。フィールド2には3つのグループがあり、第4フィールドには0と1が含まれます。AWKを使用してグループで最初のn番目の行を選択する

最初のフィールドは単なるインデックスです。

私は(グループ1のみ2行を持っていることに注意してください)次の作業

  1. は、グループ1の最初の3行を選択して行うためにAWKを使用したいです。行の数は、4番目のフィールド時間に見つかった1の数に基づいています。3

  2. グループ2の最初の6行を選択します。行の数は、4番目のフィールド時間3.

  3. 行数は4番目のフィールド時間で見つかった1の数3.

に基づいています3.だから、17行が出力のために選択されているグループの最初の9行を選択しますファイル。

ありがとうございました。

Input 

1 1 TN1148 1 
2 1 S52689 0 
3 2 TA2081 1 
4 2 TA2592 1 
5 2 TA4011 0 
6 2 TA4246 0 
7 2 TA4275 0 
8 2 TB0159 0 
9 2 TB0392 0 
10 3 TB0454 1 
11 3 TB0496 1 
12 3 TB1181 1 
13 3 TC0027 0 
14 3 TC1340 0 
15 3 TC2247 0 
16 3 TC3094 0 
17 3 TD0106 0 
18 3 TD1146 0 
19 3 TD1796 0 
20 3 TD3587 0 

Output 

1 1 TN1148 1 
2 1 S52689 0 
3 2 TA2081 1 
4 2 TA2592 1 
5 2 TA4011 0 
6 2 TA4246 0 
7 2 TA4275 0 
8 2 TB0159 0 
10 3 TB0454 1 
11 3 TB0496 1 
12 3 TB1181 1 
13 3 TC0027 0 
14 3 TC1340 0 
15 3 TC2247 0 
16 3 TC3094 0 
17 3 TD0106 0 
18 3 TD1146 0 
+0

あなたがグループと呼んでいるものとあなたがフィールドと呼んでいるものが私にはあまり明確ではないので、質問を再構成する必要があります。 awkでは、フィールドには非常に具体的な意味があり、これは問題をさらに混乱させます。 – SiegeX

+0

あなたの質問を編集して、入力/出力フォーマットが現在読めるようにしました。将来の通知のために、あなたのコードを強調表示して、CTRL + Kを押すか、エディタの "101"アイコンを押してください。 – SiegeX

+0

フィールド2には、3つの「グループ」1,2および3があります。これが明確になることを希望します。ありがとうSiegeX。 – Tony

答えて

0
#!/usr/bin/awk -f 
# by Dennis Williamson - 2010-12-02 
# for http://stackoverflow.com/questions/4334167/selecting-first-nth-rows-by-groups-using-awk 
$2 == prev { 
    count += $4 
    groupcount++ 
    array[idx++] = $0 
} 
$2 != prev { 
    if (NR > 1) { 
     for (i=0; i<count*3; i++) { 
      if (i == groupcount) break 
      print array[i] 
     } 
    } 
    prev = $2 
    count = 1 
    groupcount = 1 
    split("", array) # delete the array 
    idx = 0 
    array[idx++] = $0 
} 
END { 
    for (i=0; i<count*3; i++) { 
     if (i == groupcount) break 
     print array[i] 
    } 
} 
+0

親愛なるDennis-あなたの努力のために多くのおかげです。私はプログラムをテストしましたが、期待される出力は得られませんでした。出力には37行があり、行には順序がありません。可能な変更?乾杯。 Tony – Tony

+0

@トニー:提供したサンプルデータを使用して、その出力はサンプル出力とまったく同じです。サンプルデータから正しい結果を得ていますか?どのように動作していないのか、より具体的にすることはできますか? –

+0

Dennis-まず、私は37行及び最初の数行を持って、私はARE1 1 TN1148 1 2 1 S52689 0 3 2 TA2081 1つの 1 TN1148 1 2 1 S52689 0 ... – Tony

2

このawkプログラムへの鍵は、2回に分けて入力ファイルを渡すことです:一度あなたが望むどのように多くの行をカウントすると、一度にそれらを印刷します。

awk ' 
    NR == FNR {wanted_rows[$2] += 3*$4; next} 
    --wanted_rows[$2] >= 0 {print} 
' input_file.txt input_file.txt 
+0

親愛なるGlennWowさん、私はちょうどあなたのプログラムをテストして、うまくいきます。私は約1.8Mの行をテストするはるかに大きなファイルを持っており、あなたの投稿を維持します。 - ありがとう、ありがとう - 私は同じ入力ファイルが2回渡されたのが初めてです。この考えを決して考えないでください – Tony

+0

両方の回答が有効です。彼らはどちらも自分たちの優雅さを独占しています。 – Tony

関連する問題