查找数字,并删除与此数字相等的相邻字符

时间:2012-06-25 09:05:24

标签: perl unix sed awk

我的4列输出的一部分如下所示:

5    cc1kcc1kc    5    cc1kcc1kc
5    cc2ppggg   5    cc2ppggg
6    ccg12qqqqqqqqqqqqggg    10 ccccg11qqqqqqqqqqqggggg 
3    4qqqqcgc1q   12    cgccgccgccgc

我只想改变第二和第四列,有没有办法用awk / sed删除旁边有字符的数字? 或者使用perl脚本执行此转换会更容易/更好吗?

结果输出应如下所示:

5    ccccc    5    ccccc
5    ccggg    5    ccggg
6    ccgggg   10    ccccgggggg 
3    cgc    12    cgccgccgccgc

4 个答案:

答案 0 :(得分:4)

从字面上理解问题,这会删除字段2和4中的下一个 n 字符,用于任何 n 嵌入现场。

perl -lane 'for $i (1, 3) {@nums = $F[$i] =~ /(\d+)/g; for $num (@nums) {$F[$i] =~ s/$num.{$num}//}}; print join("\t", @F)'

其他答案会删除数字,后面跟随的所有字符都相同。

为了说明我的答案与其他答案之间的区别,请使用以下输入:

6    ccg8qqqqqqqqqqqqggg    10 ccccg3qqqqqqqqqqqggggg

我的版本输出:

6    ccgqqqqggg     10      ccccgqqqqqqqqggggg

虽然他们输出了这个:

6    ccgggg    10 ccccgggggg

答案 1 :(得分:3)

使用perl

perl -pe 's/\d+([^\d\s])\1*//g'

答案 2 :(得分:2)

使用sed:

sed 's/[0-9]\+\([a-z]\)\1*//g'

匹配找到任意数字字符串([0-9]+)后跟任何字母([a-z])。 \1*匹配该字符的任何后续出现。 /g(全局)修饰符可确保每行都执行多次替换。

答案 3 :(得分:1)

这可能适合你(GNU sed):

sed 'h;s/\S*\s*\(\S*\).*/\1/;:a;s/[^0-9]*\([0-9]\+\).*/sed "s|\1.\\{\1\\}||" <<<"&"/e;ta;H;g;/\n.*\n/bb;s/\(\S*\s*\)\{3\}\(\S*\).*/\2/;ba;:b;s/^\(\S*\s*\)\(\S*\)\([^\n]*\)\n\(\S*\)/\1\4\3/;s/\(\S*\s*\)\n\(.*\)/\2/' file