特定の列に同じ値を持つタブ区切りファイルのすべての行にif条件を適用します。

特定の列に同じ値を持つタブ区切りファイルのすべての行にif条件を適用します。

デフォルトでは、列2の値が同じ行にif条件を適用したいと思います。この例では、最初の3行の列2(Disease1)に同じ値があります。今、これらの3行にIF条件を適用したいと思います。 3 番目の列が「高」の場合、その行のみが出力ファイルに書き込まれます。 3番目の列に「high」がない場合は、「medium」を見つけて印刷します。 「media」も存在しない場合は、「low」値を含む行が印刷されます。

入力する:

id1 Disease1 High
id2 Disease1 Medium
id3 Disease1 Low
id4 Disease2 Low
id5 Disease3 Medium
id6 Disease3 Low

予想出力:

id1 Disease1 High
id4 Disease2 Low
id5 Disease3 Medium

答え1

awk 'BEGIN { FS=OFS="\t"; d["High"]=1; d["Medium"]=2; d["Low"]=3 } { print d[$3], $0 }' file |
sort -t $'\t' -k3,3 -k1,1n | sort -t $'\t' -s -u -k3,3 | cut -f 2-

残念ながら、「High」、「Medium」、および「Low」という単語はこの順序でアルファベット順にソートされないため、列3の対応する単語の各行の前に整数1、2、3を追加します。awkスクリプト。この整数は元のコンテンツとタブで区切られており、病気の重症度を表します(1が最も高い)。

次に、その整数フィールドの病気と修正データを並べ替えて、レコードを病気ごとにグループ化し、重症度別に並べ替えることができます。

その後、病気だけをコアとしてsort「ユニークにランク付け」します(2番目)。これは重複した病気をすべて削除し、各病気について最も深刻な記録のみを保存します。同じキーを持つレコードの並べ替えを維持する安定したソートアルゴリズムを使用します-ssort

最後cutに、以前に追加した整数を削除しますawk

パイプは、コマンドを指定するために使用されるフィールド区切りbash文字を想定していますsort。使用されていない場合はbash、代わりに一重引用符リテラルタブを挿入してください$'\t'(おそらくを押してこれを実行できますCtrl+V Tab)。

答え2

各Id(秒)列の優先順位が常に高いものから低い場合は、次の方法で簡単に実行できます。

sort -u -k2,2 infile

それ以外の場合は、次のようにできます。

sed 's/High$/1/; s/Medium$/2/; s/Low$/3/' infile \
| sort -k2,3  \
| sort -uk2,2 \
| sed 's/1$/High/; s/2$/Medium/; s/3$/Low/'

または単にawk

awk '{ pr[$2]=($3=="High"?$3:(pr[$2]=="High"?pr[$2]:(pr[$2]=="Medium"?pr[$2]:$3)));
       if (temp!=pr[$2]) { id[$2]=$0; temp=pr[$2] }
} END { for (key in id) print id[key] }' infile

答え3

私はPerlを使ってこのハッシュを生成するパーサを構築します。

  • 2列の値をキーとして使用
  • キーに対応する最初の行は、そのキーの値を構成します。
  • 値を設定したら、キーの他のすべての行をスキップします。

解析が完了するとハッシュを印刷し、必要に応じて2番目のトークンをソートします。

答え4

ちょうどいいです。

awk '
    BEGIN {prio["High"]=1; prio["Medium"]=2; prio["Low"]=3}
    !($2 in p) || prio[$3] < p[$2] {p[$2] = prio[$3]; line[$2] = $0}
    END {for (key in line) print line[key]}
' file
id1 Disease1 High
id4 Disease2 Low
id5 Disease3 Medium

関連情報