私はまだプログラミングを学んでおり、多くのことを試しましたが、フォーマットを正しく指定できません。私タブ区切りファイルには17個の列と多数(約50,000個)の行があります。ファイルは最初の列に基づいてソートされます。同じ最初の列(A)を持つ行をマージしたいのですが、他の16列はすべて異なり、すべての情報を1行、好ましくは同じ列に保持したいと思います。セミコロン;それらの間の区切り文字として。出力ファイルでタブ文字を区切り文字として保持したいと思います。答えてくれてありがとう。私がどこで間違っているかを説明してください。 :)
私が今まで試したこと:
awk -F'\t' 'NF>1{a[$1] = a[$1]";"$2}END{for(i in a){print i""a[i]}}' filename.txt
perl -F',' -anle 'next if /^$/;$h{$F[0]} = $h{$F[0]}.", ".$F[1];
END{print $_,$h{$_},"\n" for sort keys %h}' filename.txt
ファイル形式(残りの15列はB列と形式が同じです)
A B C
123 fvv ggg
123 kjf ggg
123 ccd att
567 abc gst
567 abc hgt
879 ttt tyt
私が望む出力(17列すべてが必要で、2〜16列にはB列とC列と同じ出力が必要です)。 BのすべてのケースはBの下にあり、CのすべてのケースはCの下になければならず、DのすべてのケースはDの下になければなりません。したがって、出力には入力と同じ17列があり、最初の列(この特定のファイルの場合)に多くの反復があるため、50,000行ではなく約20,000行が必要です。
A B C
123 fvv;kjf;ccd ggg;ggg;att
567 abc;abc gst;hgt
879 ttt lll
答え1
awk '{
if(NR!=1){a[$1]=$2";"a[$1]}
else print $0}
END{
n = asorti(a, b);
for (n in b) {
print b[n],a[b[n]]
}
}'
答え2
Perlソリューション:
$ perl -F"\t" -anle 'if($.==1){print; next} push @{$k{$F[0]}},@F[1..$#F];
END{print "$_\t" . join(";",@{$k{$_}}) for sort keys(%k)}' file
A B
123 fvv;kjf;ccd
567 abc;abc
879 ttt
これは複数のフィールドに適用できます。ただし、大量のコンテンツをメモリにロードする必要があるため、ファイルが大きい場合は問題になる可能性があります。
どこで間違っているかについては、実際に何が起こったのか説明しないとわかりません。しかし、私の頭では、次の理由でPerlの試みが失敗しました。
- 入力にタブがある場合は、
-F,
それを使用してフィールド区切り文字をコンマに設定します。 -l
とを使用していますprint "foo\n"
。各印刷呼び出しに改行文字が追加されたため、複数の空白行が-l
生成されます。- 追加を使用しているので、
$h{$F[0]}.", ".$F[1];
最初に実行して定義されていない場合は、保存された値の先頭に追加の値を追加$h{$F[0]}
します。,
- 2番目のフィールドだけを見て、他のすべてのフィールドは無視します。
awk
同様に、次の理由であなたの意志が失敗します。
- 印刷中です
foo""bar
。これにより、各フィールド間にスペースを入れずに出力がリンクされます。タブで区切られた出力が欲しいprint foo,bar
ですOFS="\t"
。 - 2番目のフィールドだけを見て、他のすべてのフィールドは無視します。
答え3
申し訳ありませんが、問題はこれです。
awk 'BEGIN{FS="\t"} {for(i=2; i<=NF; i++) { if (!a[$1]) a[$1]=$1FS$i ;else a[$1]=a[$1]";"$i};if ($1 != old) b[j++] = a[old];old=$1 } END{for (i=0; i<j; i++) print b[i] }' 1
123 fvv ;kjf;ccd
567 abc;abc
879 ttt
答え4
awk '
function p(n,A){
s = n
for(i=2;i<=NF;i++){
s = s "\t" A[i]
A[i] = $i
}
if(n)
print s
}
NR==1{
print
next
}
$1==n{
for(i=2;i<=NR;i++)
A[i] = A[i] ";" $i
next
}
{
p(n,A)
n = $1
}
END{
p(n,A)
}
' file