2016-04-27 51 views
0

我有一個4.5GB的測試文件,我正在嘗試格式化它。使用sed格式化大文件

首先,我試圖用','替換選項卡,並用"分隔每個列字段。

其次我用awk和sed格式化文件中的日期字段。

這裏是我使用的是什麼:

對於格式:

cat test_sample.csv | sed -e 's/"/""/g' | sed -e 's/\t/","/g' | sed -e 's/$/"/g' | sed -e 's/^/"/' > test_sample.csv 

對於日期:

awk 'BEGIN{FS=OFS="\",\""} NR>1{cmd = "date -d \"" $10 "\" \"+%Y-%m-%d\"";cmd | getline out; $10=out; close("uuidgen")} 1' test_sample.csv > _report.tmp && mv _report.tmp test_sample.csv 

這些命令運行過程中出現的小文件罰款,但都失敗,並清除所有文件中的數據。

請有人可以幫我格式化此文件嗎?

+0

你有(或者你可以安裝)GNU awk的時間函數嗎? –

+0

您可能不需要調用日期和getline,因此您的腳本可能更有效。如果您編輯您的問題以包含簡潔,可測試的樣本輸入和預期輸出,我們可以爲您提供幫助。實際上,在這一點上,你可能希望把它作爲一個單獨的後續問題,因爲你已經接受了這個答案。 –

回答

5

它們還清除小文件,因爲重定向首先發生,所以文件被截斷並保持爲空。

考慮:

$ cat file.txt 
A line of text 
$ cat file.txt > file.txt 
$ cat file.txt  # Empty! 

爲了避免這種情況,你必須複製到一個臨時文件–這在sed的-i選項爲你做。它可以選擇擴展:

sed -i.bak '...' 

這解決了您的文件截斷問題。

至於其他:

  • 不叫sed的很多次這樣的:

    sed 's/pattern1/replacement1/' file | sed 's/pattern2/replacement2/' | ... 
    

    這通過完整的文件,也適用於每一個命令,製作過程要慢得多。改爲:

    sed 's/pattern1/replacement1/;s/pattern2/replacement2/...' 
    

    只處理一次文件。

  • 您不必使用cat來管道入sed:sed將文件名作爲參數,您可以避免這種情況Useless Use of cat。如果組合命令並避開所有管道,更是如此,請參見下文。
  • 不要將sed和awk結合在一起。作爲一個經驗法則,如果你在任何地方使用awk,你不需要sed。

的組合單通就地sed命令可能看起來像這樣:

sed -i 's/"/""/g;s/\t/","/g;s/$/"/;s/^/"/' test_sample.csv 

,減少一切到一個awk命令(而不是一個班輪友好下去,但絕對比合並sed和awk)速度快:

awk 'BEGIN { OFS="," } 
NR > 1 { 
    gsub(/"/, "\"\"") 
    for (i = 1; i <= NF; ++i) 
     $i = "\"" $i "\"" 
    cmd = "date -d \"" $10 "\" \"+%Y-%m-%d\"" 
    cmd | getline out 
    $10 = out 
    close("uuidgen") 
    print 
}' test_sample.csv > _report.tmp && mv _report.tmp test_sample.csv 

在Mac OS中找到的BSD sed需要-i''

+0

雖然我同意你所有的答案,但我不認爲sed的管道輸出到另一個會產生太多的開銷,與使用';'鏈接它們相比。既然在這兩種情況下,sed都會將線條放回到模式空間中以對其進行修改。 –

+1

@jaypalsingh如果每行都有替換(管道和使用';'不是很大的區別),或者整個文件中只有很少的部分(由於多次處理整個文件導致大量的開銷),它是有區別的,所以我想說有些情況他們是相似的,有些地方管道速度較慢,但​​沒有一個管道速度更快的地方 - 爲什麼不把它作爲總是使用速度更快的習慣。 –

+1

對,我並不是說管道會更快,只是不太確定這是否會使事情大幅下降。我個人不喜歡管道,所以我不能抱怨。 ':)'應該解決OP問題的所有好建議。 –