我有一个包含 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
这是一种使用方法awk:
awk '{ print > substr($0,8,4) ".txt" }' file
如果第一个字段的长度可以变化,您可能更喜欢:
awk -F, '{ print > substr($2,0,4) ".txt" }' file
我认为这应该从命令行工作:
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
最好通读一次文件,然后将每一行写入文件应该去的地方。所以@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 的原因……一旦你使用它,无论你需要做什么,都很容易扩展它。)