2012-04-18 38 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中會導致整體更快的過程和更少的麻煩。