Chinaunix
标题:
配对-格式调整
[打印本页]
作者:
yinyuemi
时间:
2012-04-08 11:12
标题:
配对-格式调整
本帖最后由 yinyuemi 于 2012-04-08 14:38 编辑
最近坛里有些冷,任何方法都欢迎,sed,awk,perl ……
输入:
2 aaa
3 aaa
4 aaa
5 aaa
6 aaa
7 aaa
8 aaa
9 bbb
10 bbb
11 bbb
12 bbb
13 bbb
14 bbb
15 bbb
17 aaa
18 aaa
19 aaa
20 bbb
21 bbb
22 bbb
24 aaa
25 bbb
27 aaa
28 aaa
29 bbb
30 bbb
输出:
2 aaa 9 bbb
3 aaa 10 bbb
4 aaa 11 bbb
5 aaa 12 bbb
6 aaa 13 bbb
7 aaa 14 bbb
8 aaa 15 bbb
17 aaa 20 bbb
18 aaa 21 bbb
19 aaa 22 bbb
24 aaa 25 bbb
27 aaa 29 bbb
28 aaa 30 bbb
最后我会对大家的code进行测试,把执行效率的测试结果贴出了~(
见14楼
)
作者:
jiejie455
时间:
2012-04-08 12:01
本帖最后由 jiejie455 于 2012-04-08 12:01 编辑
awk '{if(a[$2]){a[$2]=a[$2]" "$1}else{a[$2]=$1}}END{split(a["aaa"],c," ");split(a["bbb"],d," ");for(i=1;i<=length(c);i++){print c[i]" aaa "d[i]" bbb"}}' data
复制代码
作者:
arthurscfd
时间:
2012-04-08 12:38
#!/bin/bash -
#-----------------------------------------------------------------------------
# FILE: compose.sh
# USAGE: ./compose.sh txt
#
# AUTHOR: moo (God helps those who help themselves)
# ORGANIZATION:
# CREATED: 2012-04-08 12:33:31 CST
# REVISION: 1.0
#-----------------------------------------------------------------------------
cat <<-txthere > txt
2 aaa
3 aaa
4 aaa
5 aaa
6 aaa
7 aaa
8 aaa
9 bbb
10 bbb
11 bbb
12 bbb
13 bbb
14 bbb
15 bbb
17 aaa
18 aaa
19 aaa
20 bbb
21 bbb
22 bbb
24 aaa
25 bbb
27 aaa
28 aaa
29 bbb
30 bbb
txthere
list=(
2 15
17 22
24 25
27 30
)
fn_main ()
{
for (( CNTR=0; CNTR<${#list[@]}; CNTR+=2 )); do
head=${list[$CNTR]}
tail=${list[(($CNTR+1))]}
# echo $head $tail
sec=` cat txt | sed -n -e "/^${head}\>/,/^${tail}\>/ p"`
line=`echo "$sec" | wc -l`
# echo $line
echo "$sec" | awk -v line=$line '{
if (NR <= line/2) {
txt[NR]=$0
} else {
print txt[NR-line/2], $0
}
}'
done
}
fn_main txt
# 感觉不完美,抛砖
作者:
yinyuemi
时间:
2012-04-08 12:44
回复
3#
arthurscfd
如果输入的文本有很多行的话,list 数组缺少通用性
作者:
arthurscfd
时间:
2012-04-08 12:52
回复
2#
jiejie455
很精辟,学习ing
作者:
jason680
时间:
2012-04-08 12:53
回复
1#
yinyuemi
$ perl -lane '{push(@a,"@F") if($F[-1] eq "aaa");print shift @a," @F" if($F[-1] eq "bbb")}' FILE
作者:
arthurscfd
时间:
2012-04-08 12:55
回复
4#
yinyuemi
是的,最近写东西有点不动大脑,看到问题就只想快点弄出来
作者:
yinyuemi
时间:
2012-04-08 13:01
回复
6#
jason680
8错!这个效率应该很高~
作者:
mpstat
时间:
2012-04-08 13:02
sed -rn ':a;N;/aaa$/ba;/bbb$/{s/^([^\n]+)(.*)\n([^\n]+)$/\1 \3\2/;P;D}'
复制代码
作者:
winway1988
时间:
2012-04-08 13:05
awk '/aaa/{a[++na]=$0;next}/bbb/{b[++nb]=$0}END{for(i=1;i<=na||i<=nb;i++)print a[i]?a[i]:"",b[i]?b[i]:""}'
复制代码
作者:
yinyuemi
时间:
2012-04-08 13:07
回复
9#
mpstat
相当犀利, 效率应该也很高~
作者:
yinyuemi
时间:
2012-04-08 13:10
回复
10#
winway1988
非常好,可以再进一步想下如何不在END部分打印结果,这样效率会更好~
作者:
mpstat
时间:
2012-04-08 13:31
本帖最后由 mpstat 于 2012-04-08 13:34 编辑
回复
11#
yinyuemi
export l=10000;seq $l|awk -va=$l 'BEGIN{srand();}{v=int(rand()*100);v=(a-NR)>2*v?v:int((a-NR)/2); for(i=0;i<v;++i){getline; print NR,"aaa"};for(i=0;i<v;++i){getline;print NR,"bbb"};}' > cc
复制代码
生成你的文件,改一下10000测测效率
作者:
yinyuemi
时间:
2012-04-08 14:21
本帖最后由 yinyuemi 于 2012-04-08 14:37 编辑
回复
13#
mpstat
Thanks!
测试结果如下:
环境:cygwin
CYGWIN_NT-5.1 version 1.7.11
time awk -f jiejie455.awk testfile >/dev/null
real 0m2.180s
user 0m2.030s
sys 0m0.124s
time perl -lane '{push(@a,"@F") if($F[-1] eq "aaa");print shift @a," @F" if($F[-1] eq "bbb")}' testfile >/dev/null
real 0m0.830s
user 0m0.718s
sys 0m0.061s
参考jason680的code略作修改,如下
cat jason680_m.pl
#!/bin/perl
use strict;
my @F;
my @a;
open(f,"@ARGV[0]") or die "$!";
while(<f>){
chomp;
push @a, $_ if($_ eq "aaa");
print shift @a," $_" if($_ eq "bbb");
}
close(f);
time perl jason680_m.pl testfile >/dev/null
real 0m0.245s
user 0m0.124s
sys 0m0.092s
time sed -nr -f mpstat.sed testfile >/dev/null #sed的效率有点让人失望,不过不是code的问题,我觉得mpstat的code已经很犀利了,慢的原因应该是正则部分
real 0m9.227s
user 0m9.155s
sys 0m0.046s
time awk -f winway1988.awk testfile >/dev/null
real 0m0.443s
user 0m0.358s
sys 0m0.031s
cat ss.awk # 额的awk code,比perl还是慢,求效率更高的~
/aaa/{if(t){i=t=j=0}a[i++]=$0}
/bbb/{print $0,a[j++];t=1}
time awk -f ss.awk testfile >/dev/null
real 0m0.330s
user 0m0.249s
复制代码
作者:
winway1988
时间:
2012-04-08 14:23
回复
12#
yinyuemi
试试这个
awk '/aaa/{a[++ntail]=$0}/bbb/{print a[++nhead],$0}'
复制代码
作者:
yinyuemi
时间:
2012-04-08 14:27
回复
15#
winway1988
效率提高了~
time awk -f winway1988_2.awk testfile >/dev/null
real 0m0.341s
user 0m0.265s
sys 0m0.031s
复制代码
作者:
ziyunfei
时间:
2012-04-08 15:31
awk '/aaa/{hash[++i]=$0}/bbb/{print hash[++j]"\t"$0}' file
作者:
ziyunfei
时间:
2012-04-08 15:36
重复了
作者:
dahaoshanhe
时间:
2012-04-08 15:40
回复
16#
yinyuemi
这个帖子真霸道
作者:
ziyunfei
时间:
2012-04-08 16:25
不管需要不需要 awk总会把$0切割成字段.这会耗费不少时间.就像perl用了-a.
作者:
dragon23452345
时间:
2012-04-11 16:52
提示:
作者被禁止或删除 内容自动屏蔽
作者:
jason680
时间:
2012-04-11 17:10
dragon23452345 发表于 2012-04-11 16:52
各位的代码都很精彩,不过感觉通用性不强,如果除了aaa,bbb,还有ccc,ddd配对就不行了
would you show the code for common, not just SAID it
作者:
dragon23452345
时间:
2012-04-11 18:17
提示:
作者被禁止或删除 内容自动屏蔽
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2