我在linux中有输入文件的内容,比如
test1|2|2||0|Sun,day|Jan
be,st3|1|0||0|Sunday|Feb1
nest|0|0||0|Sunday|Jul
rest,5||||0|Sunday|Aug
需要像
这样的输出 ax2.legend(self.labels,colorList[:len(self.labels)])
plt.legend()
使用tr命令用|替换它也取代了fieldvalue。我无法理解如何仅更改分隔符而不更改值。有人可以提供一些指示我可以用来执行此任务的命令和命令吗?
答案 0 :(得分:3)
使用sed:
$ sed -E ':a; s/^(([^"]*("[^"]*")?)*),/\1|/; ta; s/"//g' file
test1|2|2||0|Sun,day|Jan
be,st3|1|0||0|Sunday|Feb1
nest|0|0||0|Sunday|Jul
rest,5||||0|Sunday|Aug
如果,
出现在偶数|
之后,则,
会更改为"
。
:a
这定义了标签a
。
s/^(([^"]*("[^"]*")?)*),/\1|/
从行的开头^
开始,这将查找以下任意数量的序列:
1. `[^"]*` = zero or more non-quotes
2. `("[^"]*")?` = pairs of quotes
ta
如果之前的s
命令导致替换成功,则跳回标签a
并重试。
s/"//g
在我们用竖条替换所有未加引号的逗号后,我们删除了引号。
正如Potong所指出的,另一种更简单的解决方案是:
sed -E 's/(([^,"]*("[^"]*")*)*),/\1|/g;s/"//g' file
这是因为两个细微之处:(1)sed的正则表达式寻找最左边最长的匹配,(2)当进行全局(g)替换时,后续匹配不允许与先前的匹配重叠。考虑到这两个规则,此命令仅在偶数引号后用,
替换|
。
答案 1 :(得分:2)
使用sed
实现这是一项艰巨的任务。
另一方面,在python(版本3.x)中,完成了几行:
import csv
with open("input.csv") as fr:
with open("output.csv","w",newline='') as fw: # uncomment for python 3.x
with open("output.csv","wb") as fw: # python 2.x only
cr = csv.reader(fr,delimiter=",")
cw = csv.writer(fw,delimiter="|")
cw.writerows(cr)
工作原理:它只使用了惊人的内置csv
模块。用分隔符读取,用另一个写入。
好的,现在只是为了好玩...我的sed
解决方案,如果你真的想知道
创建一个这样的sedfile:
s/"\([^",]\+\)"/\1/g
s/"\([^"]\+\),\([^"]\+\)"/\1%\2/g
s/,/\|/g
s/%/,/g
应用它sed -f sedfile.txt input.csv > output.csv
它如何运作:
结果:
test1|2|2||0|Sun,day|Jan
be,st3|1|0||0|Sunday|Feb1
nest|0|0||0|Sunday|Jul
rest,5||||0|Sunday|Aug
每个受保护字段限制为1个昏迷(可以扩展到3个或更多......),字段不得使用%
符号。
答案 2 :(得分:1)
"(?<a>[^"]+)",
""
,
内的文字(后面紧跟a
)被捕获在命名组(?<a>[^,]*),
中
,
以,
结尾的a
以外的文字也会在命名组%+
"(?<a>[^"]+)",
"Sep"
首先在评估备用正则表达式之前完成named capture
,则不会删除引号
进一步阅读: perlre - 搜索shutdown_hook