Regexp用于删除某些列

时间:2017-02-17 16:08:32

标签: regex shell sed

我有这种格式的输入:

<apple1> <orange1> : <apple2> <orange2> : <apple3> <orange3> : ...

此输入的长度不确定,由橙色和苹果部分组成的苹果橙对组成,用冒号分隔。

我希望将此作为输出:

<apple1> <orange1> : <orange2> : <orange3> : ...

予。即所有的苹果部分,但第一次删除。

每个苹果部分宽14个字符,每个橙色部分宽19个字符。

我尝试过这样的事情:

sed -r 's/.{14}(.{19}):/\1:/g'

但这总是遇到跳过第一个苹果部分的问题。

任何人都可以提供正则表达式来解决这个问题吗?

真实世界的示例输入:

appleappleapplorangeorangeorangeo:appleappleapplorangeorangeorangeo:appleappleapplorangeorangeorangeo
foofoofoofoofobarbarbarbarbarbarb:foofoofoofoofobarbarbarbarbarbarb:foofoofoofoofobarbarbarbarbarbarb
xxxxxxxxxxxxxxooooooooooooooooooo:ppppppppppppppqqqqqqqqqqqqqqqqqqq:nnnnnnnnnnnnnnttttttttttttttttttt

输出应为:

appleappleapplorangeorangeorangeo:orangeorangeorangeo:orangeorangeorangeo
foofoofoofoofobarbarbarbarbarbarb:barbarbarbarbarbarb:barbarbarbarbarbarb
xxxxxxxxxxxxxxooooooooooooooooooo:qqqqqqqqqqqqqqqqqqq:ttttttttttttttttttt

3 个答案:

答案 0 :(得分:1)

此作业更适合awk,因为输入文件使用已知分隔符(colon在行和列中结构良好:{/ 1}}:

awk 'BEGIN{FS=OFS=":"} {for (i=2; i<=NF; i++) $i = substr($i, 15)} 1' file

appleappleapplorangeorangeorangeo:orangeorangeorangeo:orangeorangeorangeo
foofoofoofoofobarbarbarbarbarbarb:barbarbarbarbarbarb:barbarbarbarbarbarb
xxxxxxxxxxxxxxooooooooooooooooooo:qqqqqqqqqqqqqqqqqqq:ttttttttttttttttttt

此awk命令使用:作为输入+输出分隔符,并从每个记录中的第2个字段开始,将每个字段设置为15th位置的相同字段的子字符串。

答案 1 :(得分:1)

你对sed的正则表达式几乎是正确的。只需一遍又一遍地匹配“:_14_19”并删除14部分。 (注意:我在下面使用逗号作为正则表达式分隔符,因为它们更容易阅读。)

$ export A='appleappleapplorangeorangeorangeo:appleappleapplorangeorangeorangeo:appleappleapplorangeorangeorangeo:foofoofoofoofobarbarbarbarbarbarb:foofoofoofoofobarbarbarbarbarbarb:foofoofoofoofobarbarbarbarbarbarb:xxxxxxxxxxxxxxooooooooooooooooooo:ppppppppppppppqqqqqqqqqqqqqqqqqqq:nnnnnnnnnnnnnnttttttttttttttttttt'
$ echo $A | sed -Ee 's,:.{14}(.{19}),:\1,g'
appleappleapplorangeorangeorangeo:orangeorangeorangeo:orangeorangeorangeo:barbarbarbarbarbarb:barbarbarbarbarbarb:barbarbarbarbarbarb:ooooooooooooooooooo:qqqqqqqqqqqqqqqqqqq:ttttttttttttttttttt

答案 2 :(得分:0)

使用perl ..

我们的输入appleappleapplorangeorangeorangeo:appleappleapplorangeorangeorangeo:appleappleapplorangeorangeorangeo

让我们假设 a=appleappleappl(14个字符) b=orangeorangeorangeo(19个字符) c=appleappleapplorangeorangeorangeo:appleappleapplorangeorangeorangeo(该行的其余部分,是ab的重复组合。

预期输出:在第一次冒号(:)之前,ab都会被保留,并且在第一次冒号之后,只有{{1} } 保持。 $ {a} $ {b}:$ {b}:$ {b}:....(如果我错了,请纠正我)

所以这里再次回顾一下输入和输出。

我们的输入: b

预期输出: appleappleapplorangeorangeorangeo:appleappleapplorangeorangeorangeo:appleappleapplorangeorangeorangeo

请尝试以下脚本:(如前所述,这是使用perl而不是shell)。

appleappleapplorangeorangeorangeo:orangeorangeorangeo:orangeorangeorangeo

脚本输出:

%_Host@User> cat apple.pl
#!/usr/bin/perl

use strict;
use warnings;

while (<>) {
  chomp $_ ;
  my @tmp = split /:/, $_ ;
  my ($a,$b) = (substr($tmp[0],0,14), substr($tmp[0],14,19)) ;
  my $str = "$a"."$b" ;

  foreach my $i (1..$#tmp) {
    $tmp[$i] =~  s/$a//g ;
    $str .= ":"."$tmp[$i]"  ;
  }
  print "$str\n" ;
}
%_Host@User>

示例数据:

%_Host@User> cat td_apple |./apple.pl
appleappleapplorangeorangeorangeo:orangeorangeorangeo:orangeorangeorangeo
foofoofoofoofobarbarbarbarbarbarb:barbarbarbarbarbarb:barbarbarbarbarbarb
xxxxxxxxxxxxxxooooooooooooooooooo:ppppppppppppppqqqqqqqqqqqqqqqqqqq:nnnnnnnnnnnnnnttttttttttttttttttt

感谢。