フィールドの各値に対して一連のコマンドを実行します。

フィールドの各値に対して一連のコマンドを実行します。

TSVファイルがあります。列5の特定の値に対してすべての行を抽出し、3つの列を切り捨てて、一意の行数を計算しようとしています。たとえば、列 5 の文字列 "abc" の場合は、次のようにします。

awk '$5 == "abc"' file.tsv | cut -f 1-3 | sort -u | wc -l

しかし、「abc」だけでなく、列5のすべての一意の文字列に対してこれを行いたいと思います。 「for i in $5」のようなものが必要ですが、私はこの「forループ」をよく理解していません。文字列が多すぎるため、個々のコマンドを発行できません。

ここに画像の説明を入力してください。

答え1

これにより、期待される結果が印刷されます。

cut -f 1-3,5 file.tsv | sort -u | cut -f 4 | sort | uniq -c | awk '{ print $2, $1; }'

説明する:

cut -f 1-3,5 file.tsv関連列1、2、3、5抽出
sort -u固有の組み合わせの取得
cut -f 4現在の列4の元の5番目の列値のみ抽出固有値のソート
sort | uniq -cと計算列の
awk '{ print $2 "\t" $1; }'交換と出力の書式設定

答え2

あなたは次のようなものが欲しいようです

awk '{test[$5" "$1" "$2" "$3]++}END{for (t in test) print t}' file1 | cut -d' ' -f1 | sort | uniq -c

歩いた

test[$5" "$1" "$2" "$3]++ #populates an array with unique combinations of these fields
for (t in test) print t   #print each unique array index (field combination) once to STDOUT
cut -d' ' -f1             #extract what was the original 5th field
sort                      #yes, yes OK @Bodo
uniq -c                   #count the number of times it appears

出力

2 abc
1 def

編集する

@Bodoの手に敗北を認めながらも、awk実行可能な解決策を探そうという意志は残り、この醜い獣を捧げます…

awk '!test[$5" "$1" "$2" "$3]{out[$5]++;test[$5" "$1" "$2" "$3]++}
  END
  {for (o in out) print o, out[o]}' file1

関連情報