2016-03-29 54 views
1

說我有以下csv文件:擊:用引號,逗號和換行解析CSV

id,message,time 
123,"Sorry, This message 
has commas and newlines",2016-03-28T20:26:39 
456,"It makes the problem non-trivial",2016-03-28T20:26:41 

我想寫一個bash命令,將只返回時間列。即

time 
2016-03-28T20:26:39 
2016-03-28T20:26:41 

什麼是最直接的方式來做到這一點?你可以假設的標準UNIX utils的如AWK,呆子,切,grep的,等

注「」其存在逃逸和換行符,這使得瑣碎嘗試與

cut -d , -f 3 file.csv 

徒勞的可用性。

+3

使用具有真正CSV解析器的語言,而不是'bash'。 – chepner

+0

我全心全意地認同@chepner。對於這個任務,我會用'Python'或'Ruby'來代替Bash。 –

回答

6

作爲chepner said,鼓勵您使用能夠解析csv的編程語言。

這裏來了一個Python例如:

import csv 

with open('a.csv', 'rb') as csvfile: 
    reader = csv.reader(csvfile, quotechar='"') 
    for row in reader: 
     print(row[-1]) # row[-1] gives the last column 
+0

查看OP的問題。他在引號內有新的字符。 Awk不會認爲 – SriniV

+0

@realspirituals是的,那是真的。我用'python'替換了'awk'。 – hek2mgl

3

至於說here

gawk -v RS='"' 'NR % 2 == 0 { gsub(/\n/, "") } { printf("%s%s", $0, RT) }' file.csv \ 
| awk -F, '{print $NF}' 

來專門處理那些在雙引號字符串中換行,離開那些單獨是他們之外,使用GNU awk(對於RT):

gawk -v RS='"' 'NR % 2 == 0 { gsub(/\n/, "") } { printf("%s%s", $0, RT) }' file 

這個工作方式是沿着"字符分割文件,並在每個其他塊中刪除換行符。

輸出

time 
2016-03-28T20:26:39 
2016-03-28T20:26:41 

然後用awk到最後一列

0
sed -e 's/,/\n/g' file.csv | egrep ^201[0-9]- 
0

另一awk替代使用FS

$ awk -F'"' '!(NF%2){getline remainder;$0=$0 OFS remainder} 
       NR>1{sub(/,/,"",$NF); print $NF}' file 

2016-03-28T20:26:39 
2016-03-28T20:26:41 
0

我跑進嘗試處理lspci的-m輸出,當類似的事情,但嵌入式換行符需要先逃脫(雖然IFS =,應該在這裏工作,因爲它濫用bash的報價評估)。 下面是一個例子

f:13.3 "System peripheral" "Intel Corporation" "Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D Memory Controller 0 - Channel Target Address Decoder" -r01 "Super Micro Computer Inc" "Device 0838" 

而唯一合理的方法我能找到把該進的bash是沿着線:

# echo 'f:13.3 "System peripheral" "Intel Corporation" "Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D Memory Controller 0 - Channel Target Address Decoder" -r01 "Super Micro Computer Inc" "Device 0838"' | { eval array=($(cat)); declare -p array; } 
declare -a array='([0]="f:13.3" [1]="System peripheral" [2]="Intel Corporation" [3]="Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D Memory Controller 0 - Channel Target Address Decoder" [4]="-r01" [5]="Super Micro Computer Inc" [6]="Device 0838")' 
# 

不是一個完整的答案,但可以幫助!

-1
awk -F, '!/This/{print $NF}' file 

time 
2016-03-28T20:26:39 
2016-03-28T20:26:41