は、私は、ファイルがあります:複数の文字列をキーで折りたたむ方法は?例えば
key1 1212
key2 1212
key1 32332
key2 3232
key2 3232
は私が取得したいのファイル:awkでは
key1 1212,32332
key2 1212,3232,3232
は、私は、ファイルがあります:複数の文字列をキーで折りたたむ方法は?例えば
key1 1212
key2 1212
key1 32332
key2 3232
key2 3232
は私が取得したいのファイル:awkでは
key1 1212,32332
key2 1212,3232,3232
:
$ awk '{a[$1]=a[$1](a[$1]==""?"":",")$2}END{for(i in a)print i,a[i]}' file
key1 1212,32332
key2 1212,3232,3232
はの説明:
awk '{ # use awk for this kind of stuff
a[$1]=a[$1] (a[$1]=="" ? "" : ",") $2 # hash on first col and append seconds
}
END { # after everything is hashed
for(i in a) # for each entry in hash a
print i,a[i] # output key and data
}' file # oh yeah the file
編集: awkにバッファリングを行わせる代わりに(すなわち、ハッシュをa
に)、sort
を使用してファイルをソートし、そのキーとすべてのデータをカンマ区切りで出力することができます。ここでも後半のためにawkを使用して:
$ sort file | awk '$1!=p{printf "%s%s",(NR>1?ORS:""),$1}{printf "%s%s", ($1==p?",":OFS),$2;p=$1}END{print ""}'
key1 1212,32332
key2 1212,3232,3232
ここsort
しても、派手なパラメータを与えられていないが、現実の世界では、いくつかは、要求される可能性があります。 awkの部分は次のように説明し
sort file | \ # sort the file
awk ' # before feeding to awk
$1!=p { # if key is different from previous key
printf "%s%s",(NR>1?ORS:""),$1 # newline and print the key
}
{
printf "%s%s", ($1==p?",":OFS),$2 # print the data comma-separated
p=$1 # store key for comparing on the next round
}
END{
print "" # finish the last line nicely
}'
答えはたぶん大丈夫だと思いますが、私は常にテキストファイルを解析するのを避けるためにbashを使っています。非効率です。あなたはその入力ファイルがどれくらい大きいか分からないので、本当に悪いことがあります:)とBdfyはあなたのSOの評判を考慮に入れています。もし私があなたの質問にタグのpythonを追加すれば、 bashよりも使用する方が良いです。 – Drako
@Drako:「awk」は小さなファイルの場合は全く問題ないと言っています – sjsam
@sjsam私は同意しますが、入力が500MB以上になると、あなたは本当にPythonソリューションに満足しています:)可能であれば、正しいツールを使用してください。成長する時期を決して知りません。 – Drako
awk '{a[$1]=(a[$1]!="")?a[$1]","$2:$2}END{for(i in a){print i "\t" a[i]}}' file
key1 1212,32332
key2 1212,3232,3232
はそれを行う必要があります。
ファイル全体の結果をバッファリングしないようにするには(たとえば、ファイルが非常に大きい場合)、sort
とPythonのitertools.groupby
を使用できます。このようにPythonスクリプトを作成します。
# group.py
import itertools, sys
for k, g in itertools.groupby(sys.stdin, lambda x: x.split()[0]):
print(k, ",".join([x.split()[1] for x in g]))
を次に実行します。
perl -aE 'push @{$h{$F[0]}}, $F[1]; END {$"= ","; say "$_ @{$h{$_}}" for sort keys %h}' file
:
sort file | python group.py
key1 1212,32332
key2 1212,3232,3232
はそうでない場合は、このクイックPerlのワンライナーは、ハッシュの値を蓄積することで、同様に動作するはずです出力:
key1 1212,32332
key2 1212,3232,3232
それは純粋なSH/coreutilsのではないのですが、このタスクのためdatamashを使用することを検討してください:
sed -r -e 's/[[:space:]]+/ /g' < infile.txt | datamash -t ' ' -s groupby 1 collapse 2
これはbashで可能なはずですが、私はあなたの脳を破壊するのではなく、示唆している - あなたはbashのに言わせれば、より良いツールを使用する - それは、Linuxの - 間違いなくPythonを使用しています - それを使用して、タスクは簡単になります。 – Drako
私の答えに関するコメントのためにawkとpythonタグが追加されました。 –