2016-03-29 101 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