我有一个TSV,其中的字段如下:
name location 1,2,3,4,5
当我使用sed 's/\w/,/g'
时
我最终得到一个csv,其中1,2,3,4和5被认为是单独的条目。
我希望它是'1 2 3 4 5'
我尝试使用逗号运行上述命令之前将逗号转换为空格
sed 's/,/\w/g'
但是,当将空格转换回逗号时,它包括单个空格以及制表符,那么单个空格字符的正则表达式是什么?
所需的输出:
name, location,1 2 3 4 5,
答案 0 :(得分:1)
正如评论中提到的那样,CSV通常通过将值括在引号中来处理其分隔符出现在值中的情况,因此我建议您通过将每个值都括在引号中来解决此问题:
sed -E 's/([^\t]*)(\t|$)/"\1",/g'
您可以try it here。
这会在示例输出中留下逗号结尾,如果要避免它,可以使用以下命令:
sed -E 's/\t+$//;s/^/"/;s/\t/","/g;s/$/"/'
如果您的原始数据包含"
,则需要转义这些数据,您可以通过在其他数据之前添加以下替换来实现:
s/"/\\"/g
正如Ed Morton所建议的那样,我们还可以剥离尾随的空白字段:
s/\t+$//
最后,我将使用以下内容:
sed -E 's/"/\\"/g;s/\t+$//;s/^/"/;s/\t/","/g;s/$/"/'
您可以尝试here。
答案 1 :(得分:1)
要么用","
替换制表符,并用双引号引起来,要么用空格替换逗号,用逗号将制表符替换。在这两种情况下,您都会获得有效的CSV。
$ cat file
name location 1,2,3,4,5
$
$ sed 's/\t/","/g; s/^\|$/"/g' file
"name","location","1,2,3,4,5"
$
$ sed 's/,/ /g; s/\t/,/g' file
name,location,1 2 3 4 5
答案 2 :(得分:1)
在awk中:
$ awk -v OFS="," '{for(i=1;i<=NF;i++)if($i~/,/)$i="\"" $i "\"";$1=$1}1' file
name,location,"1,2,3,4,5"
解释:
$ awk -v OFS="," '{ # output delimiter to a comma *
for(i=1;i<=NF;i++) # loop all fields
if($i~/,/) # if comma in field
$i="\"" $i "\"" # surround with quotes **
$1=$1 # rebuild record
}1' file # output
*如果记录中有空格,请考虑使用awk -F"\t"
将选项卡的输入字段分隔符。
**,如果字段中用引号引起来,则应该将它们重复或转义。
答案 3 :(得分:0)
根据您的实际需求:
$ awk -F'\t' -v OFS=',' '{for (i=1;i<=NF;i++) $i="\""$i"\""} 1' file
"name","location","1,2,3,4,5"
$ awk -F'\t' -v OFS=',' '{for (i=1;i<=NF;i++) gsub(OFS," ",$i); $1=$1} 1' file
name,location,1 2 3 4 5
$ awk -F'\t' -v OFS=',' '{for (i=1;i<=NF;i++) gsub(OFS," ",$i); $(NF+1)=""} 1' file
name,location,1 2 3 4 5,
$ echo 'a"b' | awk -F'\t' -v OFS=',' '{for (i=1;i<=NF;i++) { gsub(/"/,"\"\"",$i); $i="\""$i"\"" } } 1'
"a""b"