首先,我想说我已经详尽地搜索了这个解决方案。重要的是我使用sed
或至少混合使用* nix命令行实用程序来解决此问题。在某些情况下,我正在处理格式错误的CSV文件,但我很确定它是可解决的。我只缺少一块拼图。
我想建立一个从CSV到管道的转换器。它应该解决以下问题:
","
并替换为|
",
并替换为|
,"
并替换为|
dog,"john "bud" smith",cat
(变为dog|john bud smith|cat
),
并替换为|
我用sed
命令完成了几乎所有这些操作,但是我对字段中的逗号感到难过。可能有更好的方法,但我对这个主题没有创造性的想法。一个正确的解决方案将解析此字符串:
1234,"bill","butler","1000,p"r"airie",1234,6789
到
1234|bill|butler|1000,prairie|1234|6789
这是我到目前为止所做的:
echo '1234,"bill","butler","1000,p"r"airie",1234,6789' |
sed -e 's/","/|/g' -e 's/,"/|/g' -e 's/",/|/g' -e 's/"//g'
答案 0 :(得分:2)
您可以使用perl
。 Text::Parsewords
救援:
perl -MText::ParseWords -nle 'print join "|", map {s/"//g; $_} parse_line(",",1,$_);' file
对于您的样本输入,它会产生:
1234|bill|butler|1000,prairie|1234|6789
答案 1 :(得分:0)
echo '1234,"bill","butler","1000,p"r"airie",1234,6789' |
sed -e 's/\([0-9"]\),\([0-9"]\)/\1|\2/g' -e 's/"//g'
我定义了一条规则:
, is transformed to the | if it is between numbers or quotes
以后再删除所有引号
EDIT1 看起来我的解决方案无效,但此问题有nice thread
答案 2 :(得分:0)
#!/bin/bash
l='1234,"bill","butler","1000,p"r"airie",1234,6789'
has_quote_in_quote()
{
echo $1 | grep -q '[^,]"[^,]'
}
clean_quote_in_quote ()
{
echo $1 | sed -E -e 's/([^,])"([^,])/\1\2/g'
}
parse()
{
echo $1 |grep -E -o '[^"]*|"[^"]*"'
}
pipe_unquoted_commas()
{
for f in $(parse $1); do echo $f|sed -E -e '/^[^"]/s/,/|/g'; done
}
while has_quote_in_quote $l; do b=$(clean_quote_in_quote $l); l=$b; done
echo $(printf "%s" $(pipe_unquoted_commas $b|sed 's/"//g'))
运行此产生
1234|bill|butler|1000,prairie|1234|6789
对我而言,这不是你想要的,但让我解释它是如何运作的。
has_quote_in_quote找到任何与逗号不相邻的'“'。clean_quote_in_quote删除它可以找到的所有内容,但是如果它们真的很接近,则需要多次传递,因为在这种情况下sed已超过单引号字符 - 无论是偶然的还是刻意的,你的例子都是精心挑选的。解析选择一个不带引号或引用的文本段,包括引号。在while循环中删除“引用的引号”然后转换逗号在最后一行中,删除了引号字符。
// P