修改两种模式之间的每行字符

时间:2018-03-23 06:47:13

标签: shell file vim sed

我需要修改每行中两个模式之间的某些字符。

Eample ::(文件内容保存为myfile.txt)

abc, def, 1, {,jsdfsd,kfgdsf,lgfgd}, 2, pqr, stu
abc, def, 1, {,jsdfsqwe,k,fdfsfl}, 2, pqr, stu
abc, def, 1, {,asdasdj,kgfdgdf,ldsfsdf}, 2, pqr, stu
abc, def, 1, {,jsds,kfdsf,fdsl}, 2, pqr, stu

我想编辑&保存myfile.txt,如下所述

abc, def, 1, {jsdfsd kfgdsf lgfgd}, 2, pqr, stu
abc, def, 1, {jsdfsqwe k fdfsfl}, 2, pqr, stu
abc, def, 1, {asdasdj kgfdgdf ldsfsdf}, 2, pqr, stu
abc, def, 1, {jsds kfdsf fdsl}, 2, pqr, stu

我已使用以下命令编辑&保存myfile.txt

sed '/1,/,/,2/{/1,/n;/,2/!{s/,/ /g}}' myfile.txt

这个命令没有帮助我实现我的目标。请帮助解决此问题。

7 个答案:

答案 0 :(得分:3)

在这种情况下,

awk 会更合适:

awk 'BEGIN{ FS=OFS=", " }{ gsub(/,/, " ", $4); sub(/\{ /, "{", $4) }1' file

输出:

abc, def, 1, {jsdfsd kfgdsf lgfgd}, 2, pqr, stu
abc, def, 1, {jsdfsqwe k fdfsfl}, 2, pqr, stu
abc, def, 1, {asdasdj kgfdgdf ldsfsdf}, 2, pqr, stu
abc, def, 1, {jsds kfdsf fdsl}, 2, pqr, stu

答案 1 :(得分:1)

由于您还拥有标记vim,因此您可以通过以下方式在vim中执行此操作:

:%normal 0f{vi{:s/\%V,/ /g^M

最后两个字符实际上是 Ctrl + V 后跟 Ctrl + M

答案 2 :(得分:1)

在vim中,还有可能存在前瞻和外观:

%s/\v(\{.*)@<=,(.*})@=/ /g 

匹配,{之间的每个},并用空格替换它们。

如果是这种情况,应该删除,直接{,而不是用空格替换,可以先在略微修改的版本中运行此行:

%s/\v(\{)@<=,(.*})@=/ /g 

答案 3 :(得分:1)

一种选择是在:substitute命令中使用sub-replace-expression。

:%s/{\zs[^}]*\ze}/\=substitute(submatch(0)[1:], ',', ' ', 'g')

这在你的花括号之间匹配,然后用空格替换每个,,同时避开第一个逗号。

如需更多帮助,请参阅:

:h sub-replace-expression
:h /\zs
:h submatch()
:h sublist
:h substitute()

答案 4 :(得分:0)

您能否请关注awk并告诉我这是否对您有所帮助。

awk 'match($0,/{.*}/){val=substr($0,RSTART,RLENGTH);gsub(/,/," ",val);gsub(/{ /,"{",val);gsub(/} /,"}",val);print substr($0,1,RSTART-1) val substr($0,RSTART+RLENGTH+1);next} 1'  Input_file

现在也添加非单线形式的解决方案。

awk '
match($0,/{.*}/){
  val=substr($0,RSTART,RLENGTH);
  gsub(/,/," ",val);
  gsub(/{ /,"{",val);
  gsub(/} /,"}",val);
  print substr($0,1,RSTART-1) val substr($0,RSTART+RLENGTH+1)
  next
}
1
'   Input_file

答案 5 :(得分:0)

使用vim:

:%normal! 4f,xf,r f,r 

: ........... command mode
% ........... in the whole file
normal! ..... normal mode
4f, ......... jump inside { block
x ........... delete the first comma
f, .......... jump to the next comma
r<Space> .... replace comma with space

答案 6 :(得分:0)

更多awk:

awk 'NR>1{gsub(/,/," ",$1); $0=RS $0}1' FS=} OFS=} RS={ ORS= file

awk '{gsub(/,/, " ", $2); $2="{" $2 "}"}1' FS='[{}]' OFS= file