假设我有以下几行:
1:a:b:c 2:d:e:f 3:a:b 4:a:b:c:d:e:f
如何使用sed(或perl)编辑它以便阅读:
1a1b1c 2d2e2f 3a3b 4a4b4c4d4e4f
我已经完成了这样的awk:
awk -F':' '{gsub(/:/, $1, $0); print $0}'
但需要很长时间才能完成!所以寻找更快的东西。
答案 0 :(得分:2)
'有点棘手,但可以使用sed
(假设文件data
包含示例输入):
$ sed '/^\(.\):/{
s//\1/
: retry
s/^\(.\)\([^:]*\):/\1\2\1/
t retry
}' data
1a1b1c
2d2e2f
3a3b
4a4b4c4d4e4f
$
您可以使用分号将脚本展平为一行; MacOS X上的sed
有时会有点胡思乱想并且反对某些部分,所以它被分成6行。第一行匹配以单个字符和冒号开头的行,并在识别时启动一系列操作。第一个替代品,例如,'1:'仅替换'1'。 : retry
也是分支的标签 - 这是其中的关键部分。下一个替换将复制第一个冒号上的第一个字符。如果替代品改变了任何东西,t retry
会回到标签上。最后一行界定了最初匹配行的整个操作序列。
答案 1 :(得分:2)
#!/usr/bin/perl
use warnings;
use strict;
while (<DATA>) {
if ( s/^([^:]+)// ) {
my $delim = $1;
s/:/$delim/g;
}
print;
}
__DATA__
1:a:b:c
2:d:e:f
3:a:b
4:a:b:c:d:e:f
答案 2 :(得分:1)
use feature qw/ say /;
use strict;
use warnings;
while( <DATA> ) {
chomp;
my @elements = split /:/;
my $interject = shift @elements;
local $" = $interject;
say $interject, "@elements";
}
__DATA__
1:a:b:c
2:d:e:f
3:a:b
4:a:b:c:d:e:f
或者在linux shell命令行上:
perl -aF/:/ -pe '$i=shift @F;$_=$i.join $i,@F;' infile.txt