我有一个包含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
答案 0 :(得分:6)
这是使用awk
的一种方式:
awk '{ print > substr($0,8,4) ".txt" }' file
如果第一个字段的长度可能不同,您可能更喜欢:
awk -F, '{ print > substr($2,0,4) ".txt" }' file
答案 1 :(得分: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
答案 2 :(得分: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的原因......一旦你有了它,无论你需要做什么,它都很容易扩展。)