以下の例のように、同じ名前のKOカテゴリを縮小し、配列の各カテゴリに割り当てられた遺伝子名を印刷する方法です。
私はこれを持っています:
K00002 gene_65472
K00002 gene_212051
K00002 gene_403626
K00003 gene_666
K00003 gene_5168
K00003 gene_7635
K00003 gene_12687
K00003 gene_175295
K00003 gene_647659
K00003 gene_663019
K00004 gene_88381
K00005 gene_30485
K00005 gene_193699
K00005 gene_256294
K00005 gene_307497
そしてこれが欲しい:
K00002 gene_65472 gene_212051 gene_403626
K00003 gene_666 gene_5168 gene_7635 gene_12687 gene_175295 gene_647659 gene_663019
K00004 gene_88381
K00005 gene_30485 gene_193699 gene_256294 gene_307497
次のコマンドが機能します(次から取得)。エマ・ルーオの答え):
tr -d '\r' < file| awk '$1 != p { if (p>"") {printf "\n"} printf "%s",$1; p=$1 } { printf "\t%s",$2 } END { if(p>"") {printf "\n"} }' > output
答え1
同じもの
awk '$1 != p { if (p>"") {printf "\n"} printf "%s",$1; p=$1 } { printf "\t%s",$2 } END { if(p>"") {printf "\n"} }' datafile
K00002 gene_65472 gene_212051 gene_403626
K00003 gene_666 gene_5168 gene_7635 gene_12687 gene_175295 gene_647659 gene_663019
K00004 gene_88381
K00005 gene_30485 gene_193699 gene_256294 gene_307497
別れたくない場合商標次に空白\t
に変更します。
仕組みは次のとおりです。
# Each line is processed in turn. "p" is the previous line's key field value
# Key field isn't the same as before
$1 != p {
# Flush this line if we have printed something already
if (p > "") { printf "\n" }
# Print the key field name and set it as the current key field
printf "%s", $1; p = $1
}
# Every line, print the second value on the line
{ printf "\t%s", $2 }
# No more input. Flush the line if we have already printed something
END {
if (p > "") { printf "\n" }
}
~から薄暗い コメント誰ですか作る誰もが答えると、根本的な問題は、Windowsシステムで生成されたデータファイルを使用しており、UNIX / Linuxプラットフォームで動作することを期待していることです。しないでください。または必要な場合は、まずファイルを正しい形式に変換してください。
dos2unix < datafile | awk '...' # As above
tr -d '\r' < data file | awk '...' # Also as above
答え2
文書:
K00002 gene_65472
K00002 gene_212051
K00002 gene_403626
K00003 gene_666
K00003 gene_5168
K00003 gene_7635
K00003 gene_12687
K00003 gene_654221
K00003 gene_663019
K00004 gene_88381
K00005 gene_30485
K00005 gene_193699
K00005 gene_256294
awkを使用してください:
awk '1 {if (a[$1]) {a[$1] = a[$1]" "$2} else {a[$1] = $2}} END {for (i in a) { print i,a[i]}}' file
出力:
K00002 gene_65472 gene_212051 gene_403626
K00003 gene_666 gene_5168 gene_7635 gene_12687 gene_654221 gene_663019
K00004 gene_88381
K00005 gene_30485 gene_193699 gene_256294
私はこれを取った郵便はがき参照。
答え3
ミラーを使ってhttp://johnkerl.org/miller/doc
そして
mlr --csv --implicit-csv-header --headerless-csv-output cat -n -g 1 then label a,b,c then reshape -s a,c then unsparsify --fill-with "" input.csv
この例はcsv入力です。
A,234
A,4945
B,8798
B,8798
B,790
あなたはやる
A,234,4945,
B,8798,8798,790
答え4
値にスペースがなく、スペースで区切られているとします。また、データが次の名前のファイルにあるとしますfile
(下のタブで区切られたバージョンを参照)。
for x in $(<file cut -d ' ' -f 1 | sort | uniq); do
printf '%s %s\n' "$x" "$(grep "$x" file | cut -d ' ' -f 2- | tr '\n' ' ' | sed 's/.$//')"
done
これは次のことを行います。
- 最初のフィールドの固有値を抽出します。
cut
-f 1
行の最初のブロックのみを選択し()、-d ' '
各スペースから切り捨てます()。sort | uniq
最初のフィールドの値を並べ替え、各フィールドを一度だけ出力します(またはより短く、より効率的:)sort -u
;
- それぞれ:
file
以下から関連ラインをすべて抽出しますgrep
。cut
最初のフィールドを削除するには(-f 2-
「2番目と後続のフィールドをインポートする」という意味)を使用してください。- 残りをスペースで区切られた値のリストに変換する(
tr
)。 - 最後の文字(不要なスペース)を削除するには、次のように使用します
sed
(はい、これは本当にエレガントではありません)。 - 結果を最初のフィールドの値に連結し、標準出力として印刷します。
入力がタブ区切りでタブ区切りの出力が必要な場合は、上記のコードは次のようになります。
for x in $(<file cut -f 1 | sort | uniq); do
printf '%s\t%s\n' "$x" "$(grep "$x" file | cut -f 2- | tr '\n' '\t' | sed 's/.$//')"
done
メモ:
- パフォーマンス:このアプローチの実行時間は、
awk
ソリューションベースの実行時間よりはるかに高いです。エマ・ルーオの答え)。少なくとも一段階の規模です。 - 一方、この方法は入力ファイルがソートされていない場合でも機能します。
- このソリューションは、効率的に作業を実行するための迅速で汚れた方法ですが、通常、テキストを処理するためにシェルループを使用することはお勧めできません。シェルループを使用してテキストを処理するのはなぜ悪い習慣と見なされますか?」。