我有一个空格分隔值的文件,我需要将其更改为以逗号分隔的值。但我有一些字符串列引用""
(双引号),我可能在字符串列中有空格。我需要取消"
,并且需要使用,
作为分隔符生成文件。
请帮助您使用UNIX脚本来转换它?
示例数据:
abcd "Bala Chuppala" 1 200 "" "Norway" "" ? ? 9 88
ab "Joh Tanni S V S" 200 2 ? "Swiss" 1 100 200 ?
预期输出:
abcd,Bala Chuppala,1,200,,Norway,,?,?,9,88
ab,Joh Tanni S V S,200,2,?,Swiss,1,100,200,?
由于
答案 0 :(得分:1)
这有点难看,因为我的C技能很生疏,但效果还不错......
另存为redelimit.c
并按照以下方式编译:
gcc -o redelimit redelimit.c
或
cc -o redelimit redelimit.c
然后像这样运行
./redelimit
如果要保存输出,请执行以下操作:
./redelimit > newfile.csv
它希望输入文件被称为input.csv
#include <stdio.h>
#include <string.h>
FILE *fp;
int main()
{
int i,n;
int inquotes;
char line[1024];
fp = fopen ("input.csv", "r");
/* Loop through all lines in file */
while(fgets(line, sizeof(line), fp) != NULL)
{
/* Remember if we are inside double quotes so we know what to do with spaces */
inquotes=0;
/* Parse each character in line */
int len = strlen(line);
for(i=0;i<len;i++){
/* If these are double quotes, toggle value of "inquotes" variable */
if(line[i]=='"'){
inquotes=1-inquotes;
continue;
}
if(line[i]==' '){
if(inquotes){putchar(' ');} else {putchar(',');}
continue;
}
putchar(line[i]);
}
}
fclose(fp);
}
<强>输出强>
abcd,Bala Chuppala,1,200,,Norway,,?,?,9,88
ab,Joh Tanni S V S,200,2,?,Swiss,1,100,200,?,
答案 1 :(得分:1)
在很多方面,custom C program显示的Mark Setchell是一个很好的解决方案;它简洁明了,相对容易使用。 (如果从标准输入中获取输入,或者如果没有文件名,则从标准输入读取文件名参数会更容易。对于通用工具,硬编码文件名很少是个好主意)
如果您打算尝试使用标准工具,那么您将使用正则表达式。乍一看,您选择的工具包括sed
,awk
,Perl和Python。如果您使用sed
,则它必须是具有扩展正则表达式支持的版本(至少允许替代,|
);没有它,我认为你可以安全地进行映射。事实证明,sub
中的gsub
或awk
函数不够强大;他们不支持记住字符串&#39;在替换以外的整个匹配字符串。
你需要做什么?
"Johnny ""The Singer"" Cholmondeley"
等转义规则映射到Johnny "The Singer" Cholmondeley
。即便如此,严格来说,只有另一个双引号才有效。忽略预先存在的逗号和嵌入式双引号,最简单的方法是分两步进行更换:
例如,在Perl或具有ERE支持的sed
中:
perl -p -e 's/([^ "]*|"[^"]*") /\1,/g; s/"([^"]*)"/\1/g' "$@"
sed -E -e 's/([^ "]*|"[^"]*") /\1,/g; s/"([^"]*)"/\1/g' "$@" # Mac OS X, BSD
sed -r -e 's/([^ "]*|"[^"]*") /\1,/g; s/"([^"]*)"/\1/g' "$@" # GNU
Python解决方案更冗长(或者,至少,根据我对Python的知识水平,它是):
#!/usr/bin/python
from __future__ import print_function
import re
import fileinput
ssv = re.compile(r'([^ "]*|"[^"]*") ')
qqv = re.compile(r'"([^"]*)"')
for line in fileinput.input():
line = ssv.sub(r'\1,', line)
line = qqv.sub(r'\1', line)
print(line, end='');
请注意,该脚本适用于Python 2(2.7测试,名义上为2.6,但未提前导入以前不可用)以及Python 3(3.4测试)。
答案 2 :(得分:0)
如果你对编译器有恐惧感,我在awk中做了同样的事情: - )
#!/usr/bin/awk -f
{
inq=0
len=length($0)
for(i=1;i<=len;i++){
c=substr($0,i,1)
if(c=="\""){inq=1-inq}
if(c==" "){
if(inq==1)
{
printf " "
} else {
printf ","
}
} else {
printf "%s",c
}
}
printf "\n"
}
另存为marksscript
并按此运行
chmod +x marksscript
./marksscript < input.csv