| 
 
hgx126 
初级用户
 
  
 
  
  
积分 100 
发帖 80 
注册 2008-9-12 
状态 离线
 | 
『楼 主』:
 [求助]使用sed或gawk按列替换
 
使用 LLM 解释/回答一下
  
有三个文件如下: 
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。  
以下是使用gawk来实现你需求的批处理脚本示例(假设这些文件都在当前目录下): 
 
```bash 
#!/bin/bash 
 
# 首先处理b.txt的映射关系,构建一个关联数组 
awk 'BEGIN{FS=" ";OFS=" "}NR==FNR{a=$2;next} {print $0,a}' b.txt a.txt > temp1.txt 
 
# 然后处理c.txt的映射关系,构建另一个关联数组 
awk 'BEGIN{FS=" ";OFS=" "}NR==FNR{c=$2;next} { 
    # 提取第五列的前三位 
    prefix=substr($5,1,3) 
    # 替换为对应的c.txt中的值 
    $5=c " " substr($5,4) 
    print 
}' c.txt temp1.txt > result.txt 
 
# 清理临时文件 
rm temp1.txt 
 
cat result.txt 
``` 
 
你可以将上述内容保存为一个`.sh`脚本文件,比如`process_files.sh`,然后在Linux等支持bash的环境下给脚本文件添加可执行权限`chmod +x process_files.sh`,再运行`./process_files.sh`来得到处理后的结果文件`result.txt`。 
 
解释: 
1. 第一个`awk`命令:读取`b.txt`构建关联数组`a`,键是第一列的值,值是第二列的值,然后处理`a.txt`,将`a.txt`中的第一列对应的值替换为`b.txt`中的第二列值,结果输出到`temp1.txt`。 
2. 第二个`awk`命令:读取`c.txt`构建关联数组`c`,键是第一列的值,值是第二列的值,然后处理`temp1.txt`,提取`a.txt`处理后文件中第五列的前三位,用其去关联数组`c`中查找对应的值并替换,最后将结果输出到`result.txt`。 
3. 最后清理临时文件`temp1.txt`,并输出最终的处理结果文件内容。 
    
 
  
 |   
 | 
  2010-8-18 19:14 | 
  
 | 
 | 
 
hgx126 
初级用户
 
  
 
  
  
积分 100 
发帖 80 
注册 2008-9-12 
状态 离线
 | 
『第 2 楼』:
 
 
使用 LLM 解释/回答一下
  
是这个不可能实现,还是高人暂时都不在? 
Is this impossible to achieve, or are the experts temporarily not around? 
    
 
  
 |   
 | 
  2010-8-19 22:25 | 
  
 | 
 | 
 
HAT 
版主
 
        
 
  
  
积分 9023 
发帖 5017 
注册 2007-5-31 
状态 离线
 | 
『第 3 楼』:
 
 
使用 LLM 解释/回答一下
  
不难 
可能是这个论坛会gawk的人不多 
It's not difficult. Maybe there are not many people who can use gawk in this forum. 
    
 
  
  |  
                  
  
                      |   
 | 
  2010-8-20 10:09 | 
  
 | 
 | 
 
523066680 
银牌会员
 
      SuperCleaner
  
 
积分 2362 
发帖 1133 
注册 2008-2-2 
状态 离线
 | 
 | 
  2010-8-20 10:22 | 
  
 | 
 | 
 
523066680 
银牌会员
 
      SuperCleaner
  
 
积分 2362 
发帖 1133 
注册 2008-2-2 
状态 离线
 | 
『第 5 楼』:
 
 
使用 LLM 解释/回答一下
  
那些命令我都不会,也没打算学。 
还是上批处理了
  
@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 
 
 
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 ]  
I don't know those commands and don't plan to learn them. 
Still going for batch processing
  
@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 
 
 
5411 Company Department 10000 1998-11-24 1999-11-24 Stagnant 12730101 
5416 Baoning 15600 2009-11-13 2011-11-12 Normal 12540227 
5422 Chengguan 130000 2010-6-24 2012-6-23 Normal 12510202 
5426 Shaxi 70000 2010-7-13 2020-7-13 Normal 12540214 
5427 Shizi 20000 2010-6-24 2011-6-23 Normal 12460001 
5428 Jiangnan 30000 2008-4-30 2010-4-28 Normal 12460001 
5429 Yakou 18000 2009-8-23 2010-8-22 Normal 12460001 
5430 Yuhua 4800 2003-7-11 2005-7-12 Bad debt 12810001 
5431 Tiangong 30000 2010-3-22 2011-3-21 Normal 12310001 
5432 Zhiping 9645 2010-2-13 2009-11-14 Stagnant 12750201 
5433 Baita 148217 2010-5-18 2020-5-18 Normal 12540214 
5434 Pengcheng 1000 2003-12-16 2004-12-16 Stagnant 12760001 
5435 Shuanglong 1300 2004-5-18 2004-11-18 Stagnant 12710001 
5436 Qili 180000 2010-6-16 2012-6-15 Normal 12510202 
5437 Baiya 10000 2009-11-19 2010-11-18 Normal 12460001 
5438 Feifeng 4000 2010-1-7 2011-1-6 Normal 12450301 
5439 Tianlin 20700 2009-9-28 2010-9-27 Normal 12460001 
 
=========================== 
call is costly 
Change it
  
@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 | 
  
 | 
 | 
 
hgx126 
初级用户
 
  
 
  
  
积分 100 
发帖 80 
注册 2008-9-12 
状态 离线
 | 
『第 6 楼』:
 
 
使用 LLM 解释/回答一下
  
我以前用的也是这个批处理,但速度慢。所以要求用sed和gawk处理。用sed和gawk速度可能只是上面这个批处理的几分甚至几十分之一。 
I used this batch script before too, but it's slow. So it's required to use sed and gawk for processing. The speed with sed and gawk might be just a fraction or even a few tenths of that of the above batch script. 
    
 
  
 |   
 | 
  2010-8-20 11:51 | 
  
 | 
 | 
 
523066680 
银牌会员
 
      SuperCleaner
  
 
积分 2362 
发帖 1133 
注册 2008-2-2 
状态 离线
 | 
『第 7 楼』:
 
 
使用 LLM 解释/回答一下
  
嗖噶。这样的话倒是命令比较方便了呢 
其他脚本写起来也不是很简练 
坐等 
Oh, I see. In that case, commands are indeed more convenient. Other scripts aren't very concise either. Just waiting 
    
 
  
  |  
                  
  
                    综合型编程论坛 
 
我的作品索引   |   
 | 
  2010-8-20 13:06 | 
  
 | 
 | 
 
freeants001 
中级用户
 
   
 
  
 
积分 330 
发帖 244 
注册 2006-4-14 来自 湖北 
状态 离线
 | 
『第 8 楼』:
 
 
使用 LLM 解释/回答一下
  
来段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+' '+ss; 
} 
 
while (!c.AtEndOfStream) 
{ 
    line= c.ReadLine(); 
    if(re2.test(line))continue; 
    ss=line.split(re); 
    arr_c]=ss; 
} 
 
while (!a.AtEndOfStream) 
{ 
    line= a.ReadLine(); 
    if(re2.test(line))continue; 
    ss=line.split(re); 
    d.write(arr_b]+' '+ss+' '+ss+' '+ss+' ' 
            +arr_c.substr(0,3)]+' '+ss+'\r\n') 
} 
修改下提高处理速度
 
 Last edited by freeants001 on 2010-8-20 at 16:17 ]  
Here is the optimized code: 
 
```javascript 
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 = /\s+/g; 
var re2 = /^\s*$/; 
 
function readFileAndFillObject(file, obj) { 
    var line; 
    while (!file.AtEndOfStream) { 
        line = file.ReadLine(); 
        if (re2.test(line)) continue; 
        var ss = line.split(re); 
        obj] = ss; 
    } 
} 
 
readFileAndFillObject(b, arr_b); 
readFileAndFillObject(c, arr_c); 
 
var line; 
while (!a.AtEndOfStream) { 
    line = a.ReadLine(); 
    if (re2.test(line)) continue; 
    var ss = line.split(re); 
    d.write(arr_b] +' '+ ss +' '+ ss +' '+ ss +' '+ arr_c.substr(0, 3)] +' '+ ss + '\r\n'); 
} 
 
d.close(); 
a.close(); 
b.close(); 
c.close(); 
``` 
 
The main optimizations are: 
1. Extracted the loop logic for reading files and filling objects into a separate function `readFileAndFillObject` to reduce code duplication. 
2. Added `d.close()`, `a.close()`, `b.close()`, `c.close()` at the end to close the file handles properly, which is good practice. 
3. Changed the regular expression `/ +/` to `/\s+/g` which is more general for matching one or more whitespace characters. And `/^\s+$/` to `/^\s*$/` which is more flexible to match empty lines with any amount of whitespace. 
    
 
  
 |   
 | 
  2010-8-20 13:16 | 
  
 | 
 | 
 
hgx126 
初级用户
 
  
 
  
  
积分 100 
发帖 80 
注册 2008-9-12 
状态 离线
 | 
『第 9 楼』:
 
 
使用 LLM 解释/回答一下
  
感谢freeants001,可惜我看不懂。还在想用sed或gawk。 
我是不是有点顽固?呵呵 
Thanks to freeants001, but I can't understand it. Still thinking about using sed or gawk. Am I a bit stubborn? Hehe 
    
 
  
 |   
 | 
  2010-8-20 18:05 | 
  
 | 
 | 
 
523066680 
银牌会员
 
      SuperCleaner
  
 
积分 2362 
发帖 1133 
注册 2008-2-2 
状态 离线
 | 
『第 10 楼』:
 
 
使用 LLM 解释/回答一下
  
不会啊,标题就是“使用sed或gawk按列替换” 
可惜我不会~  HAT版主快出手吧! 
No translation needed as the content is in Chinese but the user just provided that text which is in Chinese and we need to translate it. Wait, no, wait. Wait the original text is in Chinese: "不会啊,标题就是“使用sed或gawk按列替换”可惜我不会~  HAT版主快出手吧!" So translating it: "I can't do it. The title is "Replace by columns using sed or gawk". Unfortunately, I can't~ HAT moderator, please come to the rescue!" 
    
 
  
  |  
                  
  
                    综合型编程论坛 
 
我的作品索引   |   
 | 
  2010-8-20 18:30 | 
  
 | 
 | 
 
freeants001 
中级用户
 
   
 
  
 
积分 330 
发帖 244 
注册 2006-4-14 来自 湖北 
状态 离线
 | 
『第 11 楼』:
 
 
使用 LLM 解释/回答一下
  
研究下AWK,由于类C特性和正则,所以学习曲比较,下面贴代码。 
 
BEGIN { 
	while((getline<"b.txt")>0){ 
		b=$0 
	} 
	 
	while((getline<"c.txt")>0){ 
		c=$2 
	} 
} 
 
{ 
	print b,$2,$3,$4,c,$5 
} 
 
END { 
	 
} 
  
Study AWK. Due to C-like features and regular expressions, the learning curve is relatively steep. Below is the code. 
 
BEGIN { 
	while((getline<"b.txt")>0){ 
		b=$0 
	} 
	 
	while((getline<"c.txt")>0){ 
		c=$2 
	} 
} 
 
{ 
	print b,$2,$3,$4,c,$5 
} 
 
END { 
	 
} 
  
    
 
  
 |   
 | 
  2010-8-20 18:53 | 
  
 | 
 | 
 
freeants001 
中级用户
 
   
 
  
 
积分 330 
发帖 244 
注册 2006-4-14 来自 湖北 
状态 离线
 | 
『第 12 楼』:
 
 
使用 LLM 解释/回答一下
  
测试了下速度,当a.txt为9.05M时,JS用时14.500秒,AWK用时仅2.484秒,好快,看来我得认真研究一番了   
Tested the speed. When a.txt was 9.05M, JS took 14.500 seconds and AWK only took 2.484 seconds, which is really fast. It seems I need to study it carefully ; ) 
    
 
  
 |   
 | 
  2010-8-20 19:19 | 
  
 | 
 | 
 
hgx126 
初级用户
 
  
 
  
  
积分 100 
发帖 80 
注册 2008-9-12 
状态 离线
 | 
『第 13 楼』:
 
 
使用 LLM 解释/回答一下
  
freeants001兄能否把代码帖全?我对gawk使用只有一点点了解。 
前面加上gawk,后面加上a.txt执行错误? 
 
 Last edited by hgx126 on 2010-8-22 at 18:51 ] 
Brother freeants001, can you post the full code? I only have a little understanding of using gawk. There was an error when executing it by adding gawk in front and a.txt at the end? 
 
 Last edited by hgx126 on 2010-8-22 at 18:51 ] 
    
 
  
 |   
 | 
  2010-8-22 18:50 | 
  
 | 
 | 
 
freeants001 
中级用户
 
   
 
  
 
积分 330 
发帖 244 
注册 2006-4-14 来自 湖北 
状态 离线
 | 
『第 14 楼』:
 
 
使用 LLM 解释/回答一下
  
11楼代码已贴全,11楼代码保存为配置文件(awk.ini),命令行下执行: 
AWK -f   awk.ini  a.txt 
The code on floor 11 has been fully posted. Save the code on floor 11 as a configuration file (awk.ini), and execute it in the command line: 
AWK -f   awk.ini  a.txt 
    
 
  
 |   
 | 
  2010-8-22 20:38 | 
  
 | 
 | 
 
asnahu 
初级用户
 
  
 
  
  
积分 99 
发帖 53 
注册 2006-8-18 
状态 离线
 | 
『第 15 楼』:
 
 
使用 LLM 解释/回答一下
  
思路来源于freeants001: 
 
@echo off 
gawk "{ if ( ARGIND==1 ) { a = $2 } if ( ARGIND==2 ) { b = $0 } if ( ARGIND==3 ) { print b,$2,$3,$4,a,$5} }" c.txt b.txt a.txt 
pause>nul 
  
The idea comes from freeants001: 
 
@echo off 
gawk "{ if ( ARGIND==1 ) { a = $2 } if ( ARGIND==2 ) { b = $0 } if ( ARGIND==3 ) { print b,$2,$3,$4,a,$5} }" c.txt b.txt a.txt 
pause>nul 
  
    
 
  
 |   
 | 
  2010-8-30 00:49 | 
  
 |