首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >sed:在两个相似的模式之间替换一个模式,即(替换“to‘在两个”之间",“)

sed:在两个相似的模式之间替换一个模式,即(替换“to‘在两个”之间",“)
EN

Stack Overflow用户
提问于 2017-03-24 04:13:07
回答 5查看 100关注 0票数 1

我有一个csv文件,其字段由双引号(")和逗号(,)分隔,例如:

代码语言:javascript
运行
复制
"123","4"5""6","789"

但是,数据中可能有一些双引号("),即需要转换为单引号(')的4"5""6,即

我需要改变

代码语言:javascript
运行
复制
"123","4"5""6","789"

代码语言:javascript
运行
复制
"123","4'5''6","789"

我试过

代码语言:javascript
运行
复制
sed "s/\(\",\"\)\(\"\|[^\(","\)]\)*\(\",\"\)/\1'\3/"g 

但只限于(\"\|[^\(","\)]\)*

匹配"或不匹配","

但也许我需要的是

匹配"而不是","

另一种方法可以执行顺序sed,即

  1. 先找到并匹配4"5""6“
  2. 将结果传递到下一个语句并替换为4'5‘'6

但无论是哪种方式,我都不知道该怎么做。

虽然我可以先将所有的"替换为',然后重新格式化csv,但它似乎很昂贵,即sed -i -e "s/\"/'/g" -e "s/','/\",\"/g" -e "s/^'/\"/g" -e "s/'$/\"/g" myFile.csv

EN

回答 5

Stack Overflow用户

发布于 2017-03-24 06:22:30

试试这个:

代码语言:javascript
运行
复制
$ sed ':a;s/\("[^,"]*\)"\([^,].*\)/\1'\''\2/;ta' <<< '"1"23","4"5""6","78"9"'
"1'23","4'5''6","78'9"

打开双引号并跟随字符直到(但不包括)下一个关闭的"将被捕获并替换为捕获的字符串和一个单引号。

如果替换成功,ta将循环到脚本的开头以进行进一步的替换。

票数 1
EN

Stack Overflow用户

发布于 2017-03-24 05:23:46

先找到并匹配4"5""6“ 将结果传递到下一个语句并替换为4'5‘'6

这在perl中是可能的。

代码语言:javascript
运行
复制
$ echo '"123","4"5""6","789"' | perl -pe 's/"\K[^,]+(?=")/$&=~s|"|\x27|gr/ge'
"123","4'5''6","789"
  • "\K[^,]+(?=")匹配列内容,省略外部双引号,并使用查找符。
  • $&=~s|"|\x27|gr将列内容中的双引号替换为单引号
    • 使用的e修饰符允许使用Perl代码而不是替换字符串。

使用sed时,涉及到杂乱的分支

代码语言:javascript
运行
复制
$ echo '"123","4"5""6","789"' | sed -E ':a s/("[^,]+)"([^,]+")(,|$)/\1\x27\2\3/; ta'
"123","4'5''6","789"
  • :a标记标签
  • ("[^,]+)"([^,]+")(,|$)至少用一个内部双引号匹配列内容。
  • \1\x27\2\3将内部双引号替换为单引号
  • 只要有匹配,ta分支就可以标记a
票数 0
EN

Stack Overflow用户

发布于 2017-03-24 05:39:29

代码语言:javascript
运行
复制
echo '"123","4"5""6","789"'|sed -r ':a;s/^([^,]+,"[^,]*)"([^"]*",)/\1\x27\2/;ta'
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42991296

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档