我有一个文件(大小很大),其中包含行,每行都有一些字段,用逗号分隔。
从这个文件中,我必须提取几个字段并将它们转储到一个新行中。但是这里的复杂性是,最后一个字段(列)本身包含一个逗号,但该特定字段由双引号“some,thing”(简言之)标识。
让我举个例子: -
the, quick, brown, fox, jumps, right, over, the little, "lazy,dog"
此文件中有许多这样的行以逗号分隔。
最后一栏中可能有很多逗号,
现在我需要从中提取几列,为此最后一列肯定是我要提取的。
我想过使用awk,但似乎awk对分隔符的分割没有限制。
python有一个split()函数,我们可以限制no。分裂和字符串在最后一个索引中。 ['the','quick','brown','fox','jumps','right','over','little','lazy,dog']。
此外,双引号应从最终输出中删除。
我试图使用awk,因为在大文件处理上awk对我来说似乎更快。但是有可能实现这样的事情,或者我需要采用pythonic方式进行循环和分裂,这似乎有点慢。
注意: 1)没有。列是固定的。
请建议。
答案 0 :(得分:3)
这不会让你远离Python,但这似乎是一个csv
的情况,特别是当你提到要删除最后一项的引号时。
test.csv:
ay,bee,cee,dee,"ee,eff"
foo,bar,"baz,quux"
test.py:
#!/usr/bin/env python
import csv
fp = open('test.csv', 'r')
for row in csv.reader(fp):
print row
fp.close()
输出:
['ay', 'bee', 'cee', 'dee', 'ee,eff']
['foo', 'bar', 'baz,quux']
答案 1 :(得分:2)
使用python的csv
模块。
with open('myfile.txt') as data:
for line in csv.reader(data):
print line[2], line[5]
它会无缝地处理你的报价。
答案 2 :(得分:0)
是的,看起来像csv文件;)
这是sed
替代
sed 's/"\([^"]\+\)"\|\([^,]\+\), \?/\n\1\2/g'
这将为您提供一个新行中的每个标记,您可以选择您想要的标记
$ echo 'the, quick, brown, fox, jumps, right, over, the little, "lazy,foo , bar, fpp,dog"' | sed 's/"\([^"]\+\)"\|\([^,]\+\), \?/\n\1\2/g'
the
quick
brown
fox
jumps
right
over
the little
lazy,foo , bar, fpp,dog
注意第一行是空的
获得第1,第4和最后一个字段
$ echo 'the, quick, brown, fox, jumps, right, over, the little, "lazy,foo , bar, fpp,dog"' | sed 's/"\([^"]\+\)"\|\([^,]\+\), \?/\n\1\2/g' | sed -n '2p;5p;$p'
the
fox
lazy,foo , bar, fpp,dog
将所有内容放在一起(并使用 bash )
while read -r; do
sed 's/"\([^"]\+\)"\|\([^,]\+\), \?/\n\1\2/g' <<< "$REPLY" | sed -n '2p;5p;$p'
done < file
答案 3 :(得分:0)
csv模块很适合这个,我用它来解析一个csv文件并将每一行插入一个数据库,有了这个开销,可以快速处理几十万行,并且如上所述,它会自动处理报价
如果您更喜欢拆分方法,那么:
>>> string = 'the, quick, brown, fox, jumps, right, over, the little, "lazy,dog"'
>>> string = string.replace('"','').split(', ') # note the ', ' not ','
>>> print string
['the', 'quick', 'brown', 'fox', 'jumps', 'right', 'over', 'the little', 'lazy,dog']
会保留您的最后一个字段。
用awk:
$ cat tmp
the, quick, brown, fox, jumps, right, over, the little, "lazy,dog"
$ cat tmp | awk 'BEGIN { FS = ", " } ; { print $9 }'
"lazy,dog"
给你的字段,但不会删除引号,所以你必须把它传递给sed或其他东西。还要注意FS是“,”而不是“,”
$ cat tmp | awk 'BEGIN { FS = ", " } ; { print $9 }' | sed 's/"//g'
lazy,dog
然后,当然,你仍然必须做你想对数据做的任何事情,即使其中一个cl程序更快地完成一项特定任务,我发现在python结果中保留所有这些结果总体上更快的过程和更少的头痛。