Python 使用awk实用程序实现的场景

Python 使用awk实用程序实现的场景,python,linux,awk,Python,Linux,Awk,我有一个文件(非常大),其中包含行,每行都有一些字段,这些字段用逗号分隔 从这个文件中,我必须提取几个字段并将它们转储到新行中。但这里的复杂之处在于,最后一个字段(列)本身包含逗号,但该特定字段由双引号“some,thing”(比如)标识 让我举一个例子:- the, quick, brown, fox, jumps, right, over, the little, "lazy,dog" 这个文件中有许多这样的行,是用逗号分隔的 最后一列中可能有许多逗号 现在我需要从中提取几列,最后一列肯定

我有一个文件(非常大),其中包含行,每行都有一些字段,这些字段用逗号分隔

从这个文件中,我必须提取几个字段并将它们转储到新行中。但这里的复杂之处在于,最后一个字段(列)本身包含逗号,但该特定字段由双引号“some,thing”(比如)标识

让我举一个例子:-

the, quick, brown, fox, jumps, right, over, the little, "lazy,dog"
这个文件中有许多这样的行,是用逗号分隔的

最后一列中可能有许多逗号

现在我需要从中提取几列,最后一列肯定是我要提取的

我曾想过使用awk,但似乎awk对分隔符的拆分没有限制

python有一个split()函数,在该函数中,我们可以限制拆分的数量,并将字符串的数量放在最后一个索引中。 ['the','quick','brown','fox','jumps','right','over','the little','lazy,dog']

此外,应该从最终输出中删除双引号

我试图使用awk,因为awk在处理大文件时对我来说似乎更快。但是有可能实现这样的事情吗,或者我需要使用python的循环和拆分方式,这看起来有点慢

注: 1) 列数是固定的

请建议。

使用python模块

它将无缝地为您处理报价。

使用python的模块


它将无缝地为您处理报价。

这并不能让您远离Python,但似乎是这样,特别是当您提到要删除最后一项周围的报价时

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']

这并没有让您远离Python,但这似乎是一种情况,特别是当您提到要删除最后一项周围的引号时

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']

是的,看起来像是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
请注意,第一行是空的

获得第一、第四和最后一个字段

$ 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)

读取时-r;做

sed的/“\([^”]\+\)“\\\([^,]\+\),\?/\n\1\2/g'是的,看起来像一个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
请注意,第一行是空的

获得第一、第四和最后一个字段

$ 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)

读取时-r;执行

sed的/“\([^“]\+\)”\([^,]\+\),\?/\n\1\2/g'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是“not”


然后,当然,您仍然必须对数据执行任何您想执行的操作,即使其中一个cl程序更快地执行特定任务,我发现将所有这些都保存在python中会导致总体更快的过程和更少的麻烦

对我来说,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是“not”


然后,当然,您仍然必须对数据执行任何您想执行的操作,即使其中一个cl程序更快地执行特定任务,我发现将所有这些都保存在python中会导致总体更快的过程和更少的麻烦

当你去掉“懒狗”中的“,”时,你希望这仍然是最后一列,还是最后两列?另外,顺便问一下,所讨论的文件的列数是可变的还是固定的?您的标题
要使用awk实用工具实现的场景
与您的问题不匹配,该问题允许python解决方案。当您去掉“lazy,dog”中的“,”时,您希望这仍然是最后一列还是最后两列?另外,顺便问一下,所讨论的文件的列数是可变的还是固定的?您的标题
要使用awk实用工具实现的场景
与允许python解决方案的问题不匹配。是的,这可以处理,但有很多i/o操作会使处理器变慢。不是吗?它应该被缓冲。您是否尝试过此解决方案并发现awk更快?或者你只是在猜测吗?我尝试了这个解决方案,我检查了awk的输出速度是否比读取每一行的速度都快(因为它涉及太多的I/O),而且似乎慢了一点。。你说。?你的经验告诉我们。。因为我需要阅读大约5行这样的文字。可能是awk更快。我没有计时。然而,它并没有比awk版本做更多的IO。它正在文件中读取。它正在打印出你想要的零件。CSV模块始终足够快,可以满足我的需要。我想我只是说,如果你想使用python,就不要在这种任务中使用split。这太死板了。如果第三列被引用而不是最后一列呢?它再也不行了。您可能会发现,一旦引入必要的复杂性,使AWK正确处理您的输入,它就不再更快了。嗯。。我现在只是用蟒蛇的方式来