awk
私はこのテーブルで次の解決策を探しています(列1のx名、長さが異なる列2、「;」で区切られています)。
データフレーム.txt:
name1 1;2;4;8
name2 4;5;7
name3 8
name4 11;12
namex 20;21
1
存在と不在を含むこの行列に0
:
行列.txt:
1 2 4 5 7 8 11 12 20 21
name1 1 1 1 0 0 1 0 0 0 0
name2 0 0 1 1 1 0 0 0 0 0
name3 0 0 0 0 0 1 0 0 0 0
name4 0 0 0 0 0 0 1 1 0 0
namex 0 0 0 0 0 0 0 0 1 1
答え1
Awk
解決策:
awk 'BEGIN{
h = "1 2 3 4 5 6 7 8 11 12 20 21";
len = split(h, head);
print "\t\t" h
}
{
printf "%s\t", $1;
for (i = 1; i <= len; i++)
printf "%s%d", (i == 1? "" : OFS), ($2 ~ "\\<" head[i] "\\>");
print ""
}' file
h = "1 2 3 4 5 6 7 8 11 12 20 21"
-ヘッダーワイヤーlen = split(h, head)
-h
行を配列に分割しますhead
。ここで、indexは開始位置でソートされた位置、1
valueは分割されたキー値であり、len
配列サイズを含みます。print "\t\t" h
- 印刷ヘッダー先行タブ付きの行printf "%s\t", $1;
- 最初のフィールドを印刷します。$1
for (i = 1; i <= len; i++)
- 繰り返しhead
プロジェクト$2 ~ "\\<" head[i] "\\>"
- 2番目のフィールドに$2
現在アクセスされている項目が含まれていることを確認するhead[i]
出力:
1 2 3 4 5 6 7 8 11 12 20 21
name1 1 1 0 1 0 0 0 1 0 0 0 0
name2 0 0 0 1 1 0 1 0 0 0 0 0
name3 0 0 0 0 0 0 0 1 0 0 0 0
name4 0 0 0 0 0 0 0 0 1 1 0 0
namex 0 0 0 0 0 0 0 0 0 0 1 1
答え2
別のawk
方法では、まずヘッダーを直接生成し、1配列の各キーはhead
現在の入力行に存在します。そうでない場合0存在しない場合。
私たちは、数字の左端にある空の文字列と一致する数字をgrep
取得しようとしました(左と右に使用したものと同じ)。-o
\b
\<
awk
awk 'NR==FNR { !head[$1]++; next }
{ printf $1; for (x in head) { printf (x?FS:"") ($0 ~ "\\<" x "\\>") }; print ""
}' <(grep -o '\b[0-9]\+' infile) infile
出力は次のとおりです
name1 1 1 1 0 0 1 0 0 0 0
name2 0 0 1 1 1 0 0 0 0 0
name3 0 0 0 0 0 1 0 0 0 0
name4 0 0 0 0 0 0 1 1 0 0
namex 0 0 0 0 0 0 0 0 1 1
ヘッダーを生成して入力ファイルの最初の行に挿入するのはawk
簡単です。
awk 'NR==1{ split($0, head); next }
{ printf $1; for (x in head){ printf (x?FS:"") ($2 ~ "\\<" head[x] "\\>" ) };
print "" }' infile