6

10 年間のデータを含む大きなファイルがあります。それぞれ 1 年分のデータを含むファイルに分割したいと考えています。

ファイル内のデータは次の形式です。

GBPUSD,20100201,000200,1.5969,1.5969,1.5967,1.5967,4 GBPUSD,20100201,000300,1.5967,1.5967,1.5960,1.5962,4

文字 8 ~ 11 には年が含まれます。最後に .txt を付けたファイル名として使用したいと思います。したがって、2011.txt、2012.txt など

ファイルには約 400 万行が含まれています。

Ubuntu Linux を使用しています

4

3 に答える 3

7

を使用する 1 つの方法を次に示しawkます。

awk '{ print > substr($0,8,4) ".txt" }' file

最初のフィールドの長さが変わる可能性がある場合は、次のことをお勧めします。

awk -F, '{ print > substr($2,0,4) ".txt" }' file
于 2013-02-03T21:05:40.293 に答える
0

これはコマンドラインから機能するはずだと思います:

YEARS=`cat FILE | sed -e 's/^.......//' -e 's/\(....\).*$/\1/' | sort | uniq` ; for Y in $YEARS ; do echo Processing $Y... ; egrep '^.......'$Y FILE > $Y.txt ; done

于 2013-02-03T21:17:22.147 に答える
0

ファイルを一度読み込んで、各行をファイルに書き込むのが最善です。したがって、AWKを使用した@steveによるソリューションは良いものです。

この問題grepは、適切な正規表現を使用して解決できます。年の位置にある^.......2010行のみに一致します。2010次に、シェル スクリプトが何年にもわたってループし、次のgrepように実行し続けることができます。

for year in 2010 2011 2012; do
    grep "^.......$year" datafile > $year.txt
done

しかし、1 年に 1 回ソース ファイル全体を読み取るため、エレガントではありません。

これは、AWK ソリューションに沿った Python ソリューションです。

import sys

def next_line():
    if len(sys.argv) == 1:
        for line in sys.stdin:
            yield line
    else:
        for name in sys.argv[1:]:
            with open(name) as f:
                for line in f:
                    yield line


_open_files = {}
def output(fname, line):
    if fname not in _open_files:
        _open_files[fname] = open(fname, "w")
    _open_files[fname].write(line)


for line in next_line():
    year = line[7:11]
    fname = year + ".txt"
    output(fname, line)

AWK は確かに簡潔さで勝っています。各ファイルから順番にソース行を提供するサービスを提供する関数を実装するnext_line()必要がありました。ファイルを指定しなかった場合は標準入力を提供する必要がありました。AWK を使用すると、無料で入手できます。ファイル名と文字列を指定して出力を書き込むだけの関数を実装するoutput()必要がありましたが、AWK では無料で取得できます。

問題がこれ以上複雑にならない場合は、AWK ソリューションを使用できますが、時間が経つにつれてベルとホイッスルをさらに追加することが予想される場合は、Python ソリューションが効果を発揮する可能性があります。(だから、私は Python が大好きです... 一度動作するようになると、何をする必要があるとしても簡単に拡張できます。)

于 2013-02-03T21:45:07.737 に答える