如何在不编程的情况下根据特定模式替换文件中的子串

时间:2012-07-19 03:23:34

标签: vim sed awk

假设我有一个文件:

其格式应为: number,string1,[string2],....

这里string1不应该包含',',因为我们使用','来分隔每一列 但由于某种原因,string1现在包含一些','在其中, 所以我们需要用其他符号替换它,例如' - '

1,aaa,bbb,ccc,[x,y,z],eee,fff,ggg
2,q,w,[x],f,g
3,z,[y],g,h
4,zzz,xxx,ccc,vvv,[z],g,h
....

应修改为:

1,aaa-bbb-ccc,[x,y,z],eee,fff,ggg
2,q-w,[x],f,g
3,z,[y],g,h
4,zzz-xxx-ccc-vvv,[z],g,h
....

没有编程的最佳方法是什么,我的意思是我们只使用awk,sed,vim而不是shell编程,python,c ++等

由于

3 个答案:

答案 0 :(得分:1)

有点长,但您可以像这样使用sed

sed ':loop; s/\([0-9]\+,.*\)\([^,]*\),\([^,]*\)\(.*,\[\)/\1\2-\3\4/; t loop' \
     input_file

略短一点:

sed ':loop; s/\([0-9]*,[^\[,]*\),\([^\[,]*,\[\)/\1-\2/; t loop' input_file

第二个描述:

loop while there are matches                   # :loop;
  1) find numbers followed by a comma,         #   \([0-9]*,
       followed by anything not comma or '[',  #   [^\[,]*\)
  2) find comma                                #   ,
  3) find anything not ',' or '['              #   \([^\[,]*
  4) followed by a ',' and '['                 #   ,\[\)/
  5) replace the whole thing with
       match of step 1 and '-' and matches 
       from steps 3-4                          #   /\1-\2/;
end loop

                                   # t loop

答案 1 :(得分:1)

$ awk -F, 'BEGIN{OFS=FS} {two=$0;sub($1 FS,"",two);sub(/,[[].*/,"",two);gsub(/,/,"-",two); rest=$0;sub(/^[^[]*/,"",rest); print $1,two,rest}' input.txt 
1,aaa-bbb-ccc,[x,y,z],eee,fff,ggg
2,q-w,[x],f,g
3,z,[y],g,h
4,zzz-xxx-ccc-vvv,[z],g,h
$ 

让我们打破awk脚本以便于评论。

$ awk -F, '
  BEGIN { OFS=FS }
  {
    two=$0;                # Second field is based on the line...
    sub($1 FS,"",two);     # Remove the first field,
    sub(/,[[].*/,"",two);  # Remove everything from the [ onwards,
    gsub(/,/,"-",two);     # Replace commas in whatever remains.

    rest=$0;               # Last part of the line, after "two"
    sub(/^[^[]*/,"",rest); # Strip everything up to the [

    print $1,two,rest;     # Print it.
  }
' input.txt 

答案 2 :(得分:0)

这可能适合你(GNU sed):

sed -e 's/,\[/\n&/;h;s/\n.*//;s/,/-/2g;G;s/\n.*\n//' file