分隔符位于双引号内时cut命令输出异常及列提取失败问题
处理带引号CSV的列提取问题
cut命令仅能基于固定字符做简单分割,无法识别双引号包裹字段内的分隔符——比如你用cut -f2 -d","处理带引号的CSV时,会把引号内的逗号误判成分隔符,导致提取的第二列完全错误。
比如你的示例数据:
"Foo News, Videos (Android)","Foo News, Videos - Android","Foo News, Videos (Android)"
Bar News (iOS),"Bar News, Movie - iOS",Bar News & Movie (iOS)
下面提供两种可行的解决方法:
方法一:用awk自定义分隔逻辑
通过跟踪双引号的开闭状态,只把不在双引号内的逗号作为列分隔符,精准提取目标列:
awk -F',' ' { col = 1 in_quote = 0 line = $0 result = "" for (i=1; i<=length(line); i++) { c = substr(line, i, 1) if (c == "\"") { in_quote = !in_quote } if (c == "," && !in_quote) { col++ if (col == 2) { start = i + 1 } else if (col > 2) { end = i - 1 break } } } if (col >= 2) { if (end == "") end = length(line) result = substr(line, start, end - start + 1) gsub(/^"|"$/, "", result) # 去掉首尾引号(可选) print result } }' your_file.csv
这个脚本会逐字符扫描行内容,判断是否处于双引号包裹状态,找到第二列的起始和结束位置后提取内容,还可以选择去掉字段首尾的引号。
方法二:sed+cut组合处理
先把引号内的逗号替换成临时标记,避开cut的误判,提取后再恢复逗号:
sed -e 's/\("[^"]*\)/\x01\1\x01/g' your_file.csv \ | sed -e '/^"/s/,/@@@/g' \ | tr '\x01' '\n' \ | paste -sd ',' - \ | cut -d',' -f2 \ | sed -e 's/@@@/,/g'
步骤拆解:
- 用不可见字符
\x01把每个带引号的字段标记出来 - 单独处理带引号的行,把内部的逗号替换成临时标记
@@@ - 把标记符换成换行,让每个字段单独占一行
- 用paste把行重新拼接成原格式
- 用cut提取第二列
- 把临时标记换回逗号
内容的提问来源于stack exchange,提问作者user352290
相关产品推荐
相关产品推荐

