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

这是一种使用方法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

最好通读一次文件,然后将每一行写入文件应该去的地方。所以@steve 使用 AWK 的解决方案是一个很好的解决方案。

grep您可以使用适当的正则表达式来解决此问题:^.......2010仅匹配2010年份位置的行。然后一个shell脚本可以循环多年并继续运行grep,如下所示:

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

但它并不优雅,因为它每年读取一次整个源文件。

这是与 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 回答