中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
« [1] [2] »
作者:
标题: [求助]使用sed或gawk按列替换 上一主题 | 下一主题
hgx126
初级用户





积分 100
发帖 80
注册 2008-9-12
状态 离线
『楼 主』:  [求助]使用sed或gawk按列替换

有三个文件如下:
a.txt
5411 10000  1998-11-24 1999-11-24 12730101
5416 15600  2009-11-13 2011-11-12 12540227
5422 130000  2010-6-24 2012-6-23 12510202
5426 70000  2010-7-13 2020-7-13 12540214
5427 20000  2010-6-24 2011-6-23 12460001
5428 30000  2008-4-30 2010-4-28 12460001
5429 18000  2009-8-23 2010-8-22 12460001
5430 4800  2003-7-11 2005-7-12 12810001
5431 30000  2010-3-22 2011-3-21 12310001
5432 9645  2010-2-13 2009-11-14 12750201
5433 148217  2010-5-18 2020-5-18 12540214
5434 1000  2003-12-16 2004-12-16 12760001
5435 1300  2004-5-18 2004-11-18 12710001
5436 180000  2010-6-16 2012-6-15 12510202
5437 10000  2009-11-19 2010-11-18 12460001
5438 4000  2010-1-7 2011-1-6 12450301
5439 20700  2009-9-28 2010-9-27 12460001
b.txt
5411 公司部
5416 保宁
5422 城关
5426 沙溪
5427 石子
5428 江南
5429 垭口
5430 裕华
5431 田公
5432 治平
5433 白塔
5434 彭城
5435 双龙
5436 七里
5437 柏垭
5438 飞凤
5439 天林
c.txt

123 正常
124 正常
125 正常
126 逾期
127 呆滞
128 呆帐
我想用sed或gawk命令将a.txt文件中第一列(以空格作分隔符)复制到第二列,再将此列数据对应b.txt文件中的第一列,替换成b.txt中的第二列;
同时将将a.txt文件中的第五列中的前三位数据复制到第五列前,再将此列数据(复制后的数据列)对应c.txt文件中的第一列,替换成c.txt中的第二列。
替换后文件内容如下:
5411 公司部 10000  1998-11-24 1999-11-24 呆滞 12730101
5416 保宁 15600  2009-11-13 2011-11-12 正常 12540227
5422 城关 130000  2010-6-24 2012-6-23 正常 12510202
5426 沙溪 70000  2010-7-13 2020-7-13 正常 12540214
5427 石子 20000  2010-6-24 2011-6-23 正常 12460001
5428 江南 30000  2008-4-30 2010-4-28 正常 12460001
5429 垭口 18000  2009-8-23 2010-8-22 正常 12460001
5430 裕华 4800  2003-7-11 2005-7-12 呆帐 12810001
5431 田公 30000  2010-3-22 2011-3-21 正常 12310001
5432 治平 9645  2010-2-13 2009-11-14 呆滞 12750201
5433 白塔 148217  2010-5-18 2020-5-18 正常 12540214
5434 彭城 1000  2003-12-16 2004-12-16 呆滞 12760001
5435 双龙 1300  2004-5-18 2004-11-18 呆滞 12710001
5436 七里 180000  2010-6-16 2012-6-15 正常 12510202
5437 柏垭 10000  2009-11-19 2010-11-18 正常 12460001
5438 飞凤 4000  2010-1-7 2011-1-6 正常 12450301
5439 天林 20700  2009-9-28 2010-9-27 正常 12460001
求大家相助,写一批处理达到上述结果。要求:使用sed或gawk。

2010-8-18 19:14
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
hgx126
初级用户





积分 100
发帖 80
注册 2008-9-12
状态 离线
『第 2 楼』:  

是这个不可能实现,还是高人暂时都不在?

2010-8-19 22:25
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
HAT
版主





积分 9023
发帖 5017
注册 2007-5-31
状态 离线
『第 3 楼』:  

不难
可能是这个论坛会gawk的人不多



2010-8-20 10:09
查看资料  发短消息 网志   编辑帖子  回复  引用回复
523066680
银牌会员

SuperCleaner


积分 2362
发帖 1133
注册 2008-2-2
状态 离线
『第 4 楼』:  

不难
可能是现在积极的人不多



综合型编程论坛

我的作品索引
  
2010-8-20 10:22
查看资料  发送邮件  访问主页  发短消息 网志  OICQ (523066680)  编辑帖子  回复  引用回复
523066680
银牌会员

SuperCleaner


积分 2362
发帖 1133
注册 2008-2-2
状态 离线
『第 5 楼』:  

那些命令我都不会,也没打算学。
还是上批处理了
@echo off
setlocal enabledelayedexpansion
for /f "tokens=1,2" %%a in (b.txt) do (set b_%%a=%%b)
for /f "tokens=1,2" %%a in (c.txt) do (set c_%%a=%%b)

for /f "tokens=*" %%a in (a.txt) do (
   call :next %%a
)
pause
exit

:next
set tmpstr=%5
set tmpstr=%tmpstr:~0,3%
echo %1 !b_%1! %2 %3 %4 !c_%tmpstr%! %5


  Quote:
5411 公司部 10000 1998-11-24 1999-11-24 呆滞 12730101
5416 保宁 15600 2009-11-13 2011-11-12 正常 12540227
5422 城关 130000 2010-6-24 2012-6-23 正常 12510202
5426 沙溪 70000 2010-7-13 2020-7-13 正常 12540214
5427 石子 20000 2010-6-24 2011-6-23 正常 12460001
5428 江南 30000 2008-4-30 2010-4-28 正常 12460001
5429 垭口 18000 2009-8-23 2010-8-22 正常 12460001
5430 裕华 4800 2003-7-11 2005-7-12 呆帐 12810001
5431 田公 30000 2010-3-22 2011-3-21 正常 12310001
5432 治平 9645 2010-2-13 2009-11-14 呆滞 12750201
5433 白塔 148217 2010-5-18 2020-5-18 正常 12540214
5434 彭城 1000 2003-12-16 2004-12-16 呆滞 12760001
5435 双龙 1300 2004-5-18 2004-11-18 呆滞 12710001
5436 七里 180000 2010-6-16 2012-6-15 正常 12510202
5437 柏垭 10000 2009-11-19 2010-11-18 正常 12460001
5438 飞凤 4000 2010-1-7 2011-1-6 正常 12450301
5439 天林 20700 2009-9-28 2010-9-27 正常 12460001

===========================
call 消耗大
换一下了
@echo off
setlocal enabledelayedexpansion
for /f "tokens=1,2" %%a in (b.txt) do (set b_%%a=%%b)
for /f "tokens=1,2" %%a in (c.txt) do (set c_%%a=%%b)

for /f "tokens=1-5" %%a in (a.txt) do (
   set tmpstr=%%e
   set tmpstr=!tmpstr:~0,3!
   for %%t in (!tmpstr!) do (echo %%a !b_%%a! %%b %%c %%d !c_%%t! %%e)
)
pause
exit
[ Last edited by 523066680 on 2010-8-20 at 16:04 ]



综合型编程论坛

我的作品索引
  
2010-8-20 10:48
查看资料  发送邮件  访问主页  发短消息 网志  OICQ (523066680)  编辑帖子  回复  引用回复
hgx126
初级用户





积分 100
发帖 80
注册 2008-9-12
状态 离线
『第 6 楼』:  

我以前用的也是这个批处理,但速度慢。所以要求用sed和gawk处理。用sed和gawk速度可能只是上面这个批处理的几分甚至几十分之一。

2010-8-20 11:51
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
523066680
银牌会员

SuperCleaner


积分 2362
发帖 1133
注册 2008-2-2
状态 离线
『第 7 楼』:  

嗖噶。这样的话倒是命令比较方便了呢
其他脚本写起来也不是很简练
坐等



综合型编程论坛

我的作品索引
  
2010-8-20 13:06
查看资料  发送邮件  访问主页  发短消息 网志  OICQ (523066680)  编辑帖子  回复  引用回复
freeants001
中级用户




积分 330
发帖 244
注册 2006-4-14
来自 湖北
状态 离线
『第 8 楼』:  

来段JS
var fso = new ActiveXObject("Scripting.filesystemobject");
var arr_b={};
var arr_c={};
var a = fso.OpenTextFile("a.txt", 1, false);
var b = fso.OpenTextFile("b.txt", 1, false);
var c = fso.OpenTextFile("c.txt", 1, false);
var d = fso.CreateTextFile("result.txt",true);
var re =new RegExp();re.compile(/ +/);
var re2=new RegExp();re2.compile(/^\s+$/);
while (!b.AtEndOfStream)
{
    line= b.ReadLine();
    if(re2.test(line))continue;
    ss=line.split(re);
    arr_b[ss[0]]=ss[0]+' '+ss[1];
}

while (!c.AtEndOfStream)
{
    line= c.ReadLine();
    if(re2.test(line))continue;
    ss=line.split(re);
    arr_c[ss[0]]=ss[1];
}

while (!a.AtEndOfStream)
{
    line= a.ReadLine();
    if(re2.test(line))continue;
    ss=line.split(re);
    d.write(arr_b[ss[0]]+' '+ss[1]+' '+ss[2]+' '+ss[3]+' '
            +arr_c[ss[4].substr(0,3)]+' '+ss[4]+'\r\n')
}
修改下提高处理速度

[ Last edited by freeants001 on 2010-8-20 at 16:17 ]

2010-8-20 13:16
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
hgx126
初级用户





积分 100
发帖 80
注册 2008-9-12
状态 离线
『第 9 楼』:  

感谢freeants001,可惜我看不懂。还在想用sed或gawk。
我是不是有点顽固?呵呵

2010-8-20 18:05
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
523066680
银牌会员

SuperCleaner


积分 2362
发帖 1133
注册 2008-2-2
状态 离线
『第 10 楼』:  

不会啊,标题就是“使用sed或gawk按列替换”
可惜我不会~  HAT版主快出手吧!



综合型编程论坛

我的作品索引
  
2010-8-20 18:30
查看资料  发送邮件  访问主页  发短消息 网志  OICQ (523066680)  编辑帖子  回复  引用回复
freeants001
中级用户




积分 330
发帖 244
注册 2006-4-14
来自 湖北
状态 离线
『第 11 楼』:  

研究下AWK,由于类C特性和正则,所以学习曲比较,下面贴代码。
BEGIN {
        while((getline<"b.txt")>0){
                b[$1]=$0
        }
       
        while((getline<"c.txt")>0){
                c[$1]=$2
        }
}

{
        print b[$1],$2,$3,$4,c[substr($5,1,3)],$5
}

END {
       
}


2010-8-20 18:53
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
freeants001
中级用户




积分 330
发帖 244
注册 2006-4-14
来自 湖北
状态 离线
『第 12 楼』:  

测试了下速度,当a.txt为9.05M时,JS用时14.500秒,AWK用时仅2.484秒,好快,看来我得认真研究一番了

2010-8-20 19:19
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
hgx126
初级用户





积分 100
发帖 80
注册 2008-9-12
状态 离线
『第 13 楼』:  

freeants001兄能否把代码帖全?我对gawk使用只有一点点了解。
前面加上gawk,后面加上a.txt执行错误?

[ Last edited by hgx126 on 2010-8-22 at 18:51 ]

2010-8-22 18:50
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
freeants001
中级用户




积分 330
发帖 244
注册 2006-4-14
来自 湖北
状态 离线
『第 14 楼』:  

11楼代码已贴全,11楼代码保存为配置文件(awk.ini),命令行下执行:
AWK -f   awk.ini  a.txt

2010-8-22 20:38
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
asnahu
初级用户





积分 99
发帖 53
注册 2006-8-18
状态 离线
『第 15 楼』:  

思路来源于freeants001:
@echo off
gawk "{ if ( ARGIND==1 ) { a[$1] = $2 } if ( ARGIND==2 ) { b[$1] = $0 } if ( ARGIND==3 ) { print b[$1],$2,$3,$4,a[substr($5,1,3)],$5} }" c.txt b.txt a.txt
pause>nul


2010-8-30 00:49
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
« [1] [2] »
请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: