0

関連する質問: https://stackoverflow.com/posts/18164848

入力ファイルinput.txtは、タブ区切りのUnicode txtであり、

a  A   e  f  m
b  B   g  h
c  C   i  j
b  B   k  l

1列目と2列目で合わせてマージしたい。だから私はoutput.txtを取得したい

a  A   e  f  m
b  B   g  h     k  l
c  C   i  j

コードは、入力の最大列数を検出する必要があります。この例では5なので、6列目から「k l」を入れました。

実際、すべて数値の場合、Matlab を使用してこれを行うことがほとんどできました。しかし、ああ、文字だった頃、Matlab は Unicode の扱いが下手で、Matlab での Unicode の扱い方については stackoverflow を読んでいましたが、あきらめました。だから私は今pythonに目を向けました。

https://stackoverflow.com/posts/18164848のNirk は、次の行で対応できると回答しました。

awk -F\t '{a=$1 "\t" $2; $1=$2=""; x[a] = x[a] $0} END {for(y in x) print y,x[y]}'

ただし、このコードは入力ファイルと出力ファイルを指定していないようです。

4

3 に答える 3

3

awk はパイプベースの Linux コマンドです。入力ファイルをフィードして出力を取得するには、次のようにします。 awk -F\t '{a=$1 "\t" $2; $1=$2=""; x[a] = x[a] $0} END {for(y in x) print y,x[y]}' < INPUT.TXT > OUTPUT.TXT

しかし、上記のawkプログラムは、「コードは入力の最大列数を検出する必要があります。この例では5であるため、「k l」は6列目から入れられました。」

このpythonプログラムを試すことができます:

max_value_fields = 0
values = dict()

with file("input.txt") as f:
    keys = []
    for line in f:
        line    = line.strip()
        fs      = line.split('\t')

        key = '%s\t%s' % (fs[0], fs[1])
        if key not in values:
            values[key] = list()
            keys.append(key)
        values[key].append(fs[2:])

        value_fields = len(fs) - 2
        if value_fields > max_value_fields:
            max_value_fields = value_fields

with file("output.txt", 'w+') as f:
    for key in keys:
        fields = [key]
        for value_list in values[key]:
            fields.extend([value for value in value_list])
            fields.extend(['' for i in xrange(max_value_fields - len(value_list))])
        print >> f, '\t'.join(fields)
于 2013-08-11T06:35:12.897 に答える
2

データを 2 回読み取ります。最初のパスで列の最大数を特定し、2 回目のパスで行をマージします。結果は END に (基本的にランダムな順序で) 出力されます。

awk -f script.awk infile infile > outfile

$ cat script.awk 
# BEGIN block: separators
BEGIN { FS = OFS = "\t" }

# Loop #1: detect maximum number of columns
NR == FNR { max = NF > max ? NF : max ; next }

# Loop #2: merge rows
{
    k = $1 FS $2

    if (k in a) {
        for (i = 3; i <= NF; i++) {
            a[k] = a[k] OFS $i
        }
    } else {
        NF = max
        a[k] = $0
    }
}

# END block: Print results
END { for (i in a) print a[i] }
于 2013-08-11T07:32:46.937 に答える
1

これを試して:

awk '{x=$1FS$2;$1=$2="";a[x]=a[x]?a[x]FS$0:$0}END{for(x in a) print x,a[x]}' input.txt
于 2013-08-11T04:52:00.790 に答える