无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站广告联系 微信:wuyouceo QQ:184822951
查看: 26534|回复: 68

awk for dos 的简单应用(awk实例)

[复制链接]
发表于 2010-1-8 08:54:33 | 显示全部楼层 |阅读模式
awk for dos 是用于在dos下处理文本文件或者文本流的工具软件.
awk的语法:
awk '筛选条件 {命令1;命令2;命令3.....}' 文本文件名
其中"筛选条件"和{}不能同时缺省.
举例:
disk1.txt的内容,通过gdisk 1 >disk1.txt 获得
Disk  Partitions  Cylinders  Heads  Sectors  Mbytes  Model
  1        6         5169     240      63   38166.7  ST340016A
Partition  Status   Type     Volume Label   Mbytes   System   Usage
C:  1        A    PRIMARY                  8809.0  FAT32      23%
     2             EXTENDED                26686.1             70%
D:  3             LOGICAL                 10919.1  FAT32      29%
     4             LOGICAL                  9985.7  NTFS/HPFS  26%
E:  5             LOGICAL                  5781.2  FAT32      15%
     6             PRIMARY    RESTORE       2666.6  DIAGNOSTIC  7%

一、逐行显示 disk1.txt 中的内容
命令1:type disk1.txt|awk '{print $0}'
用type命令把disk1.txt显示给awk处理(更流行的说法是:用type命令把disk1.txt以一个
文本流的方式传递给awk),awk把传递过来的文本流进行分析处理逐行输出.
另一种简单的写法:
命令2:awk '{print $0}' disk1.txt
用awk直接处理disk1.txt,逐行显示
这里只是举例说明awk对文本文件和文本流的处理.
其实要达到这个逐行显示的目的只需要type disk1.txt 就可以了.
二、显示ghost用的全部分区编号\类型\百分比
awk '/LOG/;/PRI/' DISK1.TXT|AWK '{N+=1;print "1:"N,substr($0,20,3),substr($0,64,4)}'
命令包含一个管道"|",执行两个awk命令。
1.awk分析disk1.txt 内容,筛选出包含"LOG"和"PRI"的行输出
2.用awk逐行处理 "|" 传送过来的文本流,每处理一行n就增加1,同时显示"1:"和n的值,
以及该行第20,21,22三个位置的字符,该行第64,65,66,67四个位置的字符.

三、获得ghost用的最后一个硬盘分区编号
命令1.  awk '/LOG/;/PRI/' DISK1.TXT|AWK '{N+=1} END {print "1:"N}'
命令2.  awk '/LOG/;/PRI/' DISK1.TXT|AWK 'END {print "1:"FNR}'
awk分析disk1.txt 内容,筛选出包含"LOG"和"PRI"的行输出;用awk逐行处理 "|" 传送过来的文本流,最后显示"1:"和文本流总行数.


四、获得ghost用的最后一个主引导分区编号
awk '/LOG/;/PRI/' DISK1.TXT|AWK '{N+=1;print "1:"N,substr($0,20,3)}'|awk '/PRI/ {p=$1} END {print p}'

五、关于\ 和 [
awk 不能通过 print 输出"[" ,但是可以通过 printf "%%c%,91 的方式输出"[",也就是用printf以ASCII码的方式输出字符,这样我们就可以用AWK 生成 WBAT需要的菜单了。具体例子看 13 楼
ghost命令中有用到 "\",而,AWK 也不能通过 print 输出 "\",但,我们可以用同样方法输出成一个ghost命令到bat,然后运行这个bat。
比如:
gdisk 1|awk '/PRIMARY/;/LOGICA/' |AWK 'END {printf "ghost -clone,mode pdump,src=1:1,dst=1:"FNR":";printf "%%c",92;printf "System.gho -z5 -fx -sure"}'>G.BAT
得到的 G.BAT 就是你所需要的脚本。g.bat用于让ghost把镜像备份到最后一个分区。
就是用awk 分析gdisk 得到的第一硬盘分区信息并获得分区总个数,并生成对应的备份脚本g.bat。
其中 "FNR" 是AWK内置变量,用于表示文本流的总行数。

六、awk 的脚本支持(没有简单编程基础的可以不看)
对于比较复杂的awk调用,为了减少单行命令长度往往需要脚本的支持,就像dos下调用多个dos命令的时候我们常常编辑bat脚本一样。
语法: awk -f 脚本名 文本文件名  
比如:awk -f lastp.awk disk1.txt 表示用awk 调用脚本 lastp.awk 分析文本文件disk1.txt。
lastp.awk 内容如下:
BEGIN {print "获取硬盘有效分区信息及最后分区编号"}
{
if (substr($0,20,3)=="LOG") par($0);
if (substr($0,20,3)=="PRI") par($0)
}
END {print "";print "The last partition is 1:"n}


function par(partition) {
n+=1;print "1:"n,partition
}

脚本包括一个主程序和一个function(函数),功能是:显示disk1.txt 中的所有逻辑分区和主引导分区,并最终得出最后一个用于ghost的分区编号。
函数 par 的作用:接收一个变量(partition),每运行一次 par 函数就把全局变量 n 增加1,同时显示 "1:" 和n的值,以及显示接收过来的变量 partition 的内容;

主程序的作用:逐行分析文本流内容,如果该行的第20,21,22三个字符为"LOG"或者"PRI" 都要调用一次 PAR 函数,最后显示 "The last partition is 1:" 以及全局变量n 的值。
七、复杂一些的脚本
运行如下两句话实现格式化第一硬盘中c:盘以外的所有分区包括ntfs分区
gdisk 1|awk -f gdf.awk
gdisk 1 /batch:gdf.txt
-----gdf.awk---负责生成一个供gdisk调用的脚本
BEGIN {system("echo.>gdf.txt")}
{
if ($1!="C:") {
    if (substr($0,20,3)=="PRI") gdf("PRI")
    if (substr($0,20,3)=="LOG") gdf("LOG")
}
}
END {}

function gdf(p) {
        if (substr($0,5,1)==" ") {n=substr($0,6,1)} else {n=substr($0,5,2)}
        if (index($(NF-1),"NTFS")!=0)  {NTFS="/NTFS"} else {NTFS=""}
        system("echo /del /p:"n" /y >>gdf.txt" )
        system("echo /cre /"p" /for /q "NTFS" /y >>gdf.txt" )
        if (substr($0,15,1)=="A")  system("echo /act /p:"n" /y >>gdf.txt")
        }

-----------------------
1.把运行 "gdisk 1“ 获取的第一硬盘分区信息以文本流方式传递给awk , awk调用脚本文件gdf.awk对传递过来的文本流进行分析,生成gdf.txt 文件用与gdisk调用。gdf.txt 包含了逐一删除、创建、格式化、激活各个分区的gdisk指令。
2、gdisk 调用gdf.txt 对第一硬盘各分区进行格式化处理。
awk脚本解说看12楼

八、纯dos下实现 身份证号码所在地查询 具体看 16 楼

九、http://bbs.wuyou.net/forum.php?mod=viewthread&tid=158648&page=7#pid2025840 关于同时处理多个文件的尝试,用 GETLINE


AWK学习资料 awk_cai.rar (89.78 KB, 下载次数: 643)
发表于 2010-3-30 14:52:55 | 显示全部楼层
原帖由 dos时代菜鸟 于 2010-3-30 14:15 发表

1、nset 在win2000 下同样可以用。
2、可以用 gawk 的print 生成一个包含 SET 命令的 CMD 脚本,然后运行该脚本。


gawk for dos    '....{printf "....."$1}' ....

gawk for win    ".....{printf ?....?$1}".....   请赐教
回复

使用道具 举报

发表于 2010-1-8 09:30:30 | 显示全部楼层
嘿嘿,谢谢dos时代菜鸟兄的教程及所共享的软件!
回复

使用道具 举报

发表于 2010-1-8 09:48:07 | 显示全部楼层
请问楼主,这个软件和string(也是文本处理工具,猫似用法和这个一样) 有什么区别吗?
另外,问一下,这么复杂的东东,我们为什么不用edit.exe?
回复

使用道具 举报

 楼主| 发表于 2010-1-8 09:58:45 | 显示全部楼层
原帖由 userwuyou 于 2010-1-8 09:48 发表
请问楼主,这个软件和string(也是文本处理工具,猫似用法和这个一样) 有什么区别吗?
另外,问一下,这么复杂的东东,我们为什么不用edit.exe?

1、AWK 比STRINGS 更强大,用STRINGS 只能处理单一的一句文本条,而AWK可以处理成块的文本流。
     用STRINGS 处理文本,就必须在BAT里面制作 GOTO 循环,来处理文本中的每一条语句;而AWK就像XP下CMD中的FOR指令,可以自行处理整个文本流中的各文本条。
   你用STRINGS 设计一个可以自动分析硬盘分区信息并把第一分区备份到最后一个分区的脚本出来,再看看代码量就知道了。估计这里可能还需要用到FIND/NSET等辅助软件联合完成。
2、你能用EDIT 自动分析文本并筛选出需要的数据或者自动编辑出想要的脚本么?
你总不能在脚本每每运行到一半的时候,都要用户进入EDIT,然后根据需要编辑几条命令吧,如果用户明白命令的写法还可以,如果这个用户是个电脑盲怎么办?

[ 本帖最后由 dos时代菜鸟 于 2010-1-8 10:09 编辑 ]
回复

使用道具 举报

发表于 2010-1-8 10:33:23 | 显示全部楼层
楼主真是高人,不逊于葛明阳啊!
回复

使用道具 举报

 楼主| 发表于 2010-1-8 10:35:49 | 显示全部楼层
原帖由 dlwfdlikuan 于 2010-1-8 10:33 发表
楼主真是高人,不逊于葛明阳啊!


可不能这么说,我也就是在DOS下编辑一些脚本而已。
回复

使用道具 举报

发表于 2010-1-8 20:49:14 | 显示全部楼层
看来awk很强大,dos时代菜鸟,有没有这个软件的详细使用方法?
回复

使用道具 举报

发表于 2010-1-8 21:21:34 | 显示全部楼层
看来linux下的东东越来越多用于DOs中了!!!恭喜啊%
回复

使用道具 举报

 楼主| 发表于 2010-1-9 09:06:48 | 显示全部楼层
awk 还支持脚本调用。
回复

使用道具 举报

 楼主| 发表于 2010-1-9 09:25:45 | 显示全部楼层
原帖由 紫狐 于 2010-1-8 20:49 发表
看来awk很强大,dos时代菜鸟,有没有这个软件的详细使用方法?


有啊,看顶楼,已经从 dos-cn 那里弄到了一些
回复

使用道具 举报

 楼主| 发表于 2010-1-11 12:09:11 | 显示全部楼层
通过数组实现罗列英文文本中所有单词的出现次数
awk脚本
---------word.awk
{for (i=1;i<NF;i++) fields[$i]++}
END {    for (l in fields) print l,";",fields[l]    }
---------
运行 awk -f word.awk abc.txt 表示罗列 abc.txt 里面全部单词的出现次数。

通过此方法针对disk1.txt 可获得主引导分区和逻辑分区的个数
---------word.awk内容:
{for (i=1;i<NF;i++) fields[$i]++}
END { print "主="fields["PRIMARY"],"逻辑="fields["LOGICAL"]}
----------
AWK -f word.awk disk1.txt

[ 本帖最后由 dos时代菜鸟 于 2010-1-11 12:23 编辑 ]
回复

使用道具 举报

 楼主| 发表于 2010-1-11 14:27:07 | 显示全部楼层
运行如下两句话实现格式化第一硬盘中c:盘以外的所有分区包括ntfs分区
gdisk 1|awk -f gdf.awk
gdisk 1 /batch:gdf.txt
-----gdf.awk---负责生成一个供gdisk调用的脚本
BEGIN {system("echo.>gdf.txt")}
{
if ($1!="C:") {
    if (substr($0,20,3)=="PRI") gdf("PRI")
    if (substr($0,20,3)=="LOG") gdf("LOG")
}
}
END {}
function gdf(p) {
        if (substr($0,5,1)==" ") {n=substr($0,6,1)} else {n=substr($0,5,2)}
        if (index($(NF-1),"NTFS")!=0)  {NTFS="/NTFS"} else {NTFS=""}
        system("echo /del /p:"n" /y >>gdf.txt" )
        system("echo /cre /"p" /for /q "NTFS" /y >>gdf.txt" )
        if (substr($0,15,1)=="A")  system("echo /act /p:"n" /y >>gdf.txt")
        }
-----------------------

1.把运行 "gdisk 1“ 获取的第一硬盘分区信息以文本流方式传递给awk , awk调用脚本文件gdf.awk对传递过来的文本流进行分析,生成gdf.txt 文件用与gdisk调用。gdf.txt 包含了逐一删除、创建、格式化、激活各个分区的gdisk指令。
2、gdisk 调用gdf.txt 对第一硬盘各分区进行格式化处理。

---------脚本分析--------------------
1、如果分区盘符不是C:而且该分区是主分区或者逻辑分区都调用gdf函数
2、gdf函数:
如果记录的第五个字符是空格说明分区序号是一位数字,变量n取该记录的第6个字符,否则取该记录的第5,6两个字符;
如果记录的倒数第二个子段中包含"NTFS" 字样,说明该分区是NTFS格式设置变量NTFS内容是"/NTFS",否则NTFS为空;
通过system函数 调用dos指令 echo 向gdf.txt 中输入一条gdisk指令,用于删除该记录涉及的分区;
通过system函数 调用dos指令 echo 向gdf.txt 中输入一条gdisk指令,用于创建、格式化该记录涉及的分区;
如果该记录的第15个字符是"A",说明该分区激活,通过system函数 调用dos指令 echo 向gdf.txt 中输入一条gdisk指令,用于激活该记录涉及的分区。

[ 本帖最后由 dos时代菜鸟 于 2010-1-11 14:39 编辑 ]
回复

使用道具 举报

 楼主| 发表于 2010-1-11 17:56:40 | 显示全部楼层
利用awk 分析 gdisk获取的硬盘信息,生成wbat调用的菜单,给用户交互模式选择一个硬盘分区。纯dos下运行d.bat即可获得效果。
涉及软件:gdisk(EN)/wbat/awk   脚本 d.rar (831 Bytes, 下载次数: 150)
回复

使用道具 举报

发表于 2010-1-11 18:12:45 | 显示全部楼层
此贴很好很强大,不顶不行。
回复

使用道具 举报

发表于 2010-1-12 07:09:54 | 显示全部楼层
呵呵 有点难度 谢谢分享!!!
回复

使用道具 举报

 楼主| 发表于 2010-1-12 09:29:50 | 显示全部楼层
纯dos下实现身份证所在地查询
需要软件:awk/wbat 以及一个文本数据库date.txt
脚本及date.txt sfz.rar (21.71 KB, 下载次数: 119)
回复

使用道具 举报

发表于 2010-1-12 10:44:54 | 显示全部楼层
谁把这个帖子研究透了,awk的使用应就无敌了。

awk gawk文章收集
http://www.cn-dos.net/forum/view ... ge=1&highlight=
回复

使用道具 举报

 楼主| 发表于 2010-1-12 10:55:53 | 显示全部楼层
原帖由 lianjiang 于 2010-1-12 10:44 发表
谁把这个帖子研究透了,awk的使用应就无敌了。

awk gawk文章收集
http://www.cn-dos.net/forum/viewthread.php?tid=24225&fpage=1&highlight=


看一楼 学习资料 就是这些东西。呵呵
但,对于dos下,还是需要不断摸索,总结经验。
比如:
dos下命令行方式执行awk指令可以带dos变量比如: %D%,而awk脚本中就不行
dos命令行下awk无法运行(1+2)*3这样的乘法算式,而awk脚本中就可以。好在dos命令行下的除法可以用,呵呵。
比如:
echo.|awk '{print (2+3)*5}'  这样的句子就执行不了,而换成 echo.|awk '{print (2+3)/(1/5)}' 就能执行了。这或许是因为 * 在dos中是通配符的原因吧。

再比如:dos下的<和 >都有特殊用途,这样在命令行下如果用 >或者< 表示大于... 和 小于...来应用的for或者if语句中就不行了。
如13楼中 gdisk |awk '{for (i=1;i!=10;i++) if ($1~i) print $1}' >TEMPd1.txt 一句本来应该
gdisk |awk '{for (i=1;i<=10;i++) if ($1~i) print $1}' >TEMPd1.txt 但因为dos命令行下直接运行,只好把"<=9" 改成"!=10"

[ 本帖最后由 dos时代菜鸟 于 2010-1-12 11:15 编辑 ]
回复

使用道具 举报

发表于 2010-1-12 11:15:59 | 显示全部楼层
原帖由 dos时代菜鸟 于 2010-1-12 10:55 发表


看一楼 学习资料 就是这些东西。呵呵
但,对于dos下,还是需要不断摸索,总结经验。
比如:
比如:
echo.|awk '{print (2+3)*5}'  这样的句子就执行不了,而换成 echo.|awk '{print (2+3)/(1/5)}' 就能执行了。


没注意一楼就有了那些资料。 有那些东西,也就全了。
剩下的就是实践了。
不同版本在命令格式上有差别,这是正常的。
这只有在实践中摸索总结了。
我用的版本,执行echo.|awk '{print (2+3)*5}' 是没问题的。

snap0473.jpg
回复

使用道具 举报

 楼主| 发表于 2010-1-12 11:17:55 | 显示全部楼层
原帖由 lianjiang 于 2010-1-12 11:15 发表


没注意一楼就有了那些资料。 有那些东西,也就全了。
剩下的就是实践了。
不同版本在命令格式上有差别,这是正常的。
这只有在实践中摸索总结了。
我用的版本,执行echo.|awk '{print (2+3)*5}' 是没问 ...


gawk for 纯dos 么?来一个,品尝一下啊。
回复

使用道具 举报

发表于 2010-1-12 11:20:40 | 显示全部楼层
原帖由 dos时代菜鸟 于 2010-1-12 11:17 发表


gawk for 纯dos 么?来一个,品尝一下啊。


dos版gawk。

gawk.rar

86.97 KB, 下载次数: 656, 下载积分: 无忧币 -2

dos版gawk

回复

使用道具 举报

 楼主| 发表于 2010-1-12 12:44:09 | 显示全部楼层
原帖由 lianjiang 于 2010-1-12 11:20 发表


dos版gawk。


2.15 版本的,不错。多谢。
回复

使用道具 举报

发表于 2010-1-12 13:08:33 | 显示全部楼层
当时也是看到了dos联盟的那个帖子,有了一点试试的兴趣,网上到处找dos版,结果基本上都属无功而返。呵呵。
dos版很难找。
回复

使用道具 举报

 楼主| 发表于 2010-1-12 13:38:46 | 显示全部楼层
原帖由 lianjiang 于 2010-1-12 13:08 发表
当时也是看到了dos联盟的那个帖子,有了一点试试的兴趣,网上到处找dos版,结果基本上都属无功而返。呵呵。
dos版很难找。


刚才进行品尝了一下这个gawk,发现可能是因为体积的问题,无法在内存装载两个gawk.exe 导致 13 楼 那个脚本中 awk '{system("call d.bat a "$1 )}' tempd1.txt 的命令无法完成。

需要修改脚本,刚修改了内容如下:
------------d.bat 内容:
@echo off
cls
ECHO 正在获取硬盘个数....
gdisk |gawk '{for (i=1;i!=10;i++) if ($1~i) print $1}' >TEMPd1.txt
echo :part "选择硬盘分区"[x]>part.txt
echo 编号,盘符,状态,类型,卷标,容量,格式 >>part.txt
echo @echo off >d1.bat
gawk -f d.awk TEMPd1.txt >>d1.bat
call d1.bat
if exist d1.bat del d1.bat
if exist tempd1.txt del TEMPd1.txt
if not exist part.txt goto end1

:menu
gawk 'END {print "set dn="FNR}' part.txt >set_dn.bat
call set_dn.bat
del set_dn.bat
if *%dn%*==*2* goto error1
:2
cls
call w.bat box @part.txt:part
if errorlevel 100 goto error0
goto 答案
:error0
echo 用户放弃了选择!
goto end2
:答案
gawk 'NR==(%?%+2) {n=length($1)-2;print "用户选择了 " substr($1,2,n)}' part.txt
:end2
FOR %%c IN (wbat ?) do SET %%c=
GOto end1

:error1
echo 没有适合操作的硬盘或分区!

:end1
set dn=
if exist part.txt del part.txt

------------------d.awk内容(输出信息将传递给d1.bat)
BEGIN {}
{
  print "echo 正在分析HD"$1
  printf "gdisk "$1" "
  printf "%c",124
  printf "gawk -f d1.awk -v d="$1
  printf "%c%c",62,62;print "part.txt"
}
END {}

---------------------------------d1.awk 内容(输出信息将传递给part.txt)
BEGIN {}
{
  if ((substr($0,20,3)=="PRI")  || (substr($0,20,3)=="LOG") ) {

        n=n+1
        printf "%c",91;print d":"n"]",substr($0,2,2),substr($0,15)

     }
}
END {}


1、获取硬盘个数生成tempd1.txt
2、根据tempd1.txt 生成一个可以逐一获取各硬盘分区信息并将可用信息转化成wbat菜单条目追加到part.txt 的脚本 d1.bat
    d1.bat 包涵的命令大致是:gdisk 1 | awk -f d1.awk -v d=1 >>part.txt  如果有多个硬盘,d1.bat中会有多条这样的命令.
3、运行d1.bat 把信息追加到part.txt中
4、用wbat 调用part.txt

其中:printf "%c",62 表示输出一个">" ;printf "%c",124 表示输出一个"|"

[ 本帖最后由 dos时代菜鸟 于 2010-1-12 18:10 编辑 ]
回复

使用道具 举报

发表于 2010-1-12 15:41:58 | 显示全部楼层
不知道能否自动搜索和替换文本内容,下一个收藏。
回复

使用道具 举报

 楼主| 发表于 2010-1-12 15:49:57 | 显示全部楼层
原帖由 wmjm 于 2010-1-12 15:41 发表
不知道能否自动搜索和替换文本内容,下一个收藏。


给个题目让我看看。
回复

使用道具 举报

发表于 2010-1-12 16:25:53 | 显示全部楼层
学习了的确好用,谢谢
awk '/Key/ {print $2}' ghststat.txt|awk '/1:/ {p=$1} END {print p}|nset bakp=$1 一句就能找到最后盘符
回复

使用道具 举报

发表于 2010-1-12 16:44:56 | 显示全部楼层
一看标题以为是linux下的awk^_^
回复

使用道具 举报

 楼主| 发表于 2010-1-12 17:28:13 | 显示全部楼层
想起n年前曾经盛行一时的 foxbase+ DBASEIII 等等数据库处理语言的祖宗来,也是用c语言编辑的。很类似。
回复

使用道具 举报

 楼主| 发表于 2010-1-12 17:29:58 | 显示全部楼层
原帖由 oym2007 于 2010-1-12 16:25 发表
学习了的确好用,谢谢
awk '/Key/ {print $2}' ghststat.txt|awk '/1:/ {p=$1} END {print p}|nset bakp=$1 一句就能找到最后盘符


终于有人反馈使用感受了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2024-3-29 14:07

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表