2012-04-18 37 views
0

我有一个文件(文件大小很大),其中包含行,每行都有一些以逗号分隔的字段。使用awk实用程序实现的场景

从这个文件中,我必须提取几个字段并将它们转储到一个新行。但这里的复杂性在于,最后一个字段(列)本身包含逗号,但该特定字段由双引号“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)No。的列是固定的。

请建议。

+0

当你摆脱“懒惰,狗”中的',',你想这仍然是最后一列,或两个?此外,作为一个旁边,是有问题的文件变量或固定的列数? – Levon 2012-04-18 16:04:22

+0

您的标题'使用awk实用程序实现的场景'与您的允许使用python解决方案的问题不匹配。 – MattH 2012-04-18 16:08:44

回答

2

使用python的csv模块。

with open('myfile.txt') as data: 
    for line in csv.reader(data): 
     print line[2], line[5] 

它会为您无缝处理报价。

+0

是的,这可以处理,但有很多I/O操作,使处理器变慢。 Isnt'd? – geek 2012-04-18 16:09:00

+1

它应该被缓冲。你试过这个解决方案,发现awk更快吗?或者你只是猜测? – Useless 2012-04-18 16:13:30

+0

我试过这个解决方案,并且我检查了awk给出的输出比为每行读取做得更快(因为它涉及太多的I/O)并且似乎慢得多..你说。你的经验说,因为有5crore这样的线我需要阅读。 – geek 2012-04-18 16:15:43

3

这不会让你远离Python,但这似乎是一个csv的情况下,特别是当你提到想要删除最后一项的引号。

test.csv:

ay,bee,cee,dee,"ee,eff" 
foo,bar,"baz,quux" 

测试。潘岳:

#!/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'] 
+0

这将做循环I/O操作..我的文件是非常大,这将需要太多的处理器时间.. – geek 2012-04-18 16:10:12

+1

@ user1080454:AWK使用隐式循环。 – 2012-04-18 16:12:54

+0

螨是..但我用awk检查了同样的事情,它在2-3分钟内给出5crore行的结果。如果这种特殊情况不会发生在那里。 awk事情不会发生这种情况。 – geek 2012-04-18 16:16:55

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 

把所有在一起(使用庆典

while read -r; do 
    sed 's/"\([^"]\+\)"\|\([^,]\+\), \?/\n\1\2/g' <<< "$REPLY" | sed -n '2p;5p;$p' 
done < file 
0

的Python似乎对我来说是一个更好的选择。

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中会导致整体更快的过程和更少的麻烦。