教程一
9.1 调用awk 9.2 awk脚本 ARGC支持命令行中传入awk脚本的参数个数。ARGV是ARGC的参数排列数组,其中每一元素表示为ARGV[n],n为希望访问的命令行参数 awk printf修饰符 awk printf格式 # print a header first # let's add the scores of points gained # finished processing now let's print the total and average point 9.2.14 向awk脚本传值 从指定文本里找出匹配条件的项及其出现的次数 # finished processing so print out the matches..for each array for (senior_or_junior in student) print "The club has", student[senior_or_junior], senior_or_junior, "students"} 2、将数据文件中的每个词的第一个字母变成大写 dingyi@backup:~$ awk ',1,1); sub(/^./,toupper(first),); print }' test 下面是文件一,文件二 $cat file2 怎样的shell才能使file1、file2两个文件的$2不同的话,取出全局$0? 请大虾执教 li2002 2003-9-11 08:57 不就是找出不同行吗? deathcult 2003-9-11 09:15 paste file1 file2|awk '{if(($1==$3)&&($2!=$4))print$0}' bjgirl 2003-9-11 09:38 [code] killua 2003-9-11 10:05 回一楼,最近在学awk啦,而且你那样得到的数值是
三楼的答案是错的,我要是结果是 [color=red]00002 31 32 admirer 2003-9-12 00:45 这不是一个简单的paste能解决的问题,而是一个以关键字连接的问题! killua 2003-9-12 03:30
[quote][i]原帖由 "yoof"]join -j1 1 f1 f2 请版主解释[/quote 发表:[/i] 以第一个文件的第一个域为索引键,连接f1,f2两个文件 文件处理 1.有文件gz.txt(工资) 4367422926350133100 张三 1250.00 4367422926351220178 李四 1300.00 4367422926351220546 王二 0 苏五丙 1340.00 4367422926351220178 孙六月 1390.00 …… …… 要求:按账号19位、姓名8位、工资8位来排列,且如姓名不足8位在之后补足,工资不足8位则在工资之前补。同时要求去掉工资为0的名单,没有账号在前补19位空格,并输出工资总数加以核对,处理后应如下排列: 4367422926350133100张三 1250.00 4367422926351220178李四 1300.00 苏五丙 1340.00 4367422926351220178孙六月 1390.00 …… …… awk程序: #------------------------------------ #shgz1.sh sblank=" " awk '$nf!="0"' $1 > tmp.txt #删除工资为0的人数 awk '< if($1!~/[0-9]/)< printf("%-19.19s%-8.8s%8.2f\n","'"$kk"'",$1,$2)> #如果没有账号补上空格 else< printf("%-19.19s%-8.8s%8.2f\n",$1,$2,$3)> >' tmp.txt > $2 awk '$nf~/[0-9]/< sum=sum+$nf > end< system("rm tmp.txt") printf("the sum is%16.2f!\n", sum) #输出工资总数 >' $2 在awk中调用系统变量必须用单引号,如果是双引号,则表示字符串 如何删除匹配之间的内容但不包括匹配行 我有这样一个文件: score E awk -v p=1 '/score/{p=0}/>/{p=1}p' urfile |
教程二
awk的调用方式 前面曾经说过,awk提供了适应多种需要的不同解决方案,它们是: 一、 awk命令行,你可以象使用普通UNIX命令一样使用awk,在命令行中你也可以使用awk程序设计语言,虽然awk支持多行的录入,但是录入长长的命令行并保证其正确无误却是一件令人头疼的事,因此,这种方法一般只用于解决简单的问题。当然,你也可以在shell script程序中引用awk命令行甚至awk程序脚本。 二、使用-f选项调用awk程序。awk允许将一段awk程序写入一个文本文件,然后在awk命令行中用-f选项调用并执行这段程序。具体的方法我们将在后面的awk语法中讲到。 三、利用命令解释器调用awk程序:利用UNIX支持的命令解释器功能,我们可以将一段awk程序写入文本文件,然后在它的第一行加上: $awk脚本文本名 待处理文件 awk的语法: 与其它UNIX命令一样,awk拥有自己的语法: awk [ -F re] [parameter...] ['prog'] [-f progfile][in_file...] 参数说明: -F re:允许awk更改其字段分隔符。 parameter: 该参数帮助为不同的变量赋值。 'prog': awk的程序语句段。这个语句段必须用单拓号:'和'括起,以防被shell解释。这个程序语句段的标准形式为: 'pattern {action}' 其中pattern参数可以是egrep正则表达式中的任何一个,它可以使用语法/re/再加上一些样式匹配技巧构成。与sed类似,你也可以使用","分开两样式以选择某个范围。关于匹配的细节,你可以参考附录,如果仍不懂的话,找本UNIX书学学grep和sed(本人是在学习ed时掌握匹配技术的)。 action参数总是被大括号包围,它由一系统awk语句组成,各语句之间用";"分隔。awk解释它们,并在pattern给定的样式匹配的记录上执行其操作。与shell类似,你也可以使用“#”作为注释符,它使“#”到行尾的内容成为注释,在解释执行时,它们将被忽略。你可以省略pattern和 action之一,但不能两者同时省略,当省略pattern时没有样式匹配,表示对所有行(记录)均执行操作,省略action时执行缺省的操作——在标准输出上显示。 -f progfile:允许awk调用并执行progfile指定有程序文件。progfile是一个文本文件,他必须符合awk的语法。 in_file:awk的输入文件,awk允许对多个输入文件进行处理。值得注意的是awk不修改输入文件。如果未指定输入文件,awk将接受标准输入,并将结果显示在标准输出上。awk支持输入输出重定向。 awk的记录、字段与内置变量: 前面说过,awk处理的工作与数据库的处理方式有相同之处,其相同处之一就是awk支持对记录和字段的处理,其中对字段的处理是grep和sed不能实现的,这也是awk优于二者的原因之一。在awk中,缺省的情况下总是将文本文件中的一行视为一个记录,而将一行中的某一部分作为记录中的一个字段。为了操作这些不同的字段,awk借用shell的方法,用$1,$2,$3...这样的方式来顺序地表示行(记录)中的不同字段。特殊地,awk用$0表示整个行(记录)。不同的字段之间是用称作分隔符的字符分隔开的。系统默认的分隔符是空格。awk允许在命令行中用-F re的形式来改变这个分隔符。事实上,awk用一个内置的变量FS来记忆这个分隔符。awk中有好几个这样的内置变量,例如,记录分隔符变量RS、当前工作的记录数NR等等,本文后面的附表列出了全部的内置变量。这些内置的变量可以在awk程序中引用或修改,例如,你可以利用NR变量在模式匹配中指定工作范围,也可以通过修改记录分隔符RS让一个特殊字符而不是换行符作为记录的分隔符。 例:显示文本文件myfile中第七行到第十五行中以字符%分隔的第一字段,第三字段和第七字段: awk -F % 'NR==7,NR==15 {printf $1 $3 $7}' awk的内置函数 awk 之所以成为一种优秀的程序设计语言的原因之一是它吸收了某些优秀的程序设计语言(例如C)语言的许多优点。这些优点之一就是内置函数的使用,awk定义并支持了一系列的内置函数,由于这些函数的使用,使得awk提供的功能更为完善和强大,例如,awk使用了一系列的字符串处理内置函数(这些函数看起来与C 语言的字符串处理函数相似,其使用方式与C语言中的函数也相差无几),正是由于这些内置函数的使用,使awk处理字符串的功能更加强大。本文后面的附录中列有一般的awk所提供的内置函数,这些内置函数也许与你的awk版本有些出入,因此,在使用之前,最好参考一下你的系统中的联机帮助。 作为内置函数的一个例子,我们将在这里介绍awk的printf函数,这个函数使得awk与c语言的输出相一致。实际上,awk中有许多引用形式都是从C语言借用过来的。如果你熟悉C语言,你也许会记得其中的printf函数,它提供的强大格式输出功能曾经带我们许多的方便。幸运的是,我们在awk中又和它重逢了。awk中printf几乎与C语言中一模一样,如果你熟悉C语言的话,你完全可以照C语言的模式使用awk中的printf。因此在这里,我们只给出一个例子,如果你不熟悉的话,请随便找一本C语言的入门书翻翻。 例:显示文件myfile中的行号和第3字段: $awk '{printf"%03d%s\n",NR,$1}' myfile 在命令行使用awk 按照顺序,我们应当讲解awk程序设计的内容了,但在讲解之前,我们将用一些例子来对前面的知识进行回顾,这些例子都是在命令行中使用的,由此我们可以知道在命令行中使用awk是多么的方便。这样做的原因一方面是为下面的内容作铺垫,另一方面是介绍一些解决简单问题的方法,我们完全没有必要用复杂的方法来解决简单的问题----既然awk提供了较为简单的方法的话。 例:显示文本文件mydoc匹配(含有)字符串"sun"的所有行。 $awk '/sun/{print}' mydoc 由于显示整个记录(全行)是awk的缺省动作,因此可以省略action项。 $awk '/sun/' mydoc 例:下面是一个较为复杂的匹配的示例: $awk '/[Ss]un/,/[Mm]oon/ {print}' myfile 它将显示第一个匹配Sun或sun的行与第一个匹配Moon或moon的行之间的行,并显示到标准输出上。 例:下面的示例显示了内置变量和内置函数length()的使用: $awk 'length($0)>80 {print NR}' myfile 该命令行将显示文本myfile中所有超过80个字符的行号,在这里,用$0表示整个记录(行),同时,内置变量NR不使用标志符'$'。 例:作为一个较为实际的例子,我们假设要对UNIX中的用户进行安全性检查,方法是考察/etc下的passwd文件,检查其中的passwd字段(第二字段)是否为"*",如不为"*",则表示该用户没有设置密码,显示出这些用户名(第一字段)。我们可以用如下语句实现: #awk -F: '$2=="" {printf("%s no password!\n",$1' /etc/passwd 在这个示例中,passwd文件的字段分隔符是“:”,因此,必须用-F:来更改默认的字段分隔符,这个示例中也涉及到了内置函数printf的使用。 awk的变量 如同其它程序设计语言一样,awk允许在程序语言中设置变量,事实上,提供变量的功能是程序设计语言的其本要求,不提供变量的程序设计语言本人还从未见过。 awk 提供两种变量,一种是awk内置的变量,这前面我们已经讲过,需要着重指出的是,与后面提到的其它变量不同的是,在awk程序中引用内置变量不需要使用标志符"$"(回忆一下前面讲过的NR的使用)。awk提供的另一种变量是自定义变量。awk允许用户在awk程序语句中定义并调用自已的变量。当然这种变量不能与内置变量及其它awk保留字相同,在awk中引用自定义变量必须在它前面加上标志符"$"。与C语言不同的是,awk中不需要对变量进行初始化, awk根据其在awk中第一次出现的形式和上下文确定其具体的数据类型。当变量类型不确定时,awk默认其为字符串类型。这里有一个技巧:如果你要让你的 awk程序知道你所使用的变量的明确类型,你应当在在程序中给它赋初值。在后面的实例中,我们将用到这一技巧。 运算与判断: 作为一种程序设计语言所应具有的特点之一,awk支持多种运算,这些运算与C语言提供的几本相同:如+、-、*、/、%等等,同时,awk也支持C语言中类似++、--、+=、-=、=+、=-之类的功能,这给熟悉C语言的使用者编写awk程序带来了极大的方便。作为对运算功能的一种扩展,awk还提供了一系列内置的运算函数(如log、sqr、cos、sin等等)和一些用于对字符串进行操作(运算)的函数(如length、substr等等)。这些函数的引用大大的提高了awk的运算功能。 作为对条件转移指令的一部分,关系判断是每种程序设计语言都具备的功能,awk也不例外。 awk中允许进行多种测试,如常用的==(等于)、!=(不等于)、>(大于)、<(小于)、>=(大于等于)、>=(小于等于)等等,同时,作为样式匹配,还提供了~(匹配于)和!~(不匹配于)判断。 作为对测试的一种扩充,awk也支持用逻辑运算符:!(非)、&&(与)、||(或)和括号()进行多重判断,这大大增强了awk的功能。本文的附录中列出了awk所允许的运算、判断以及操作符的优先级。 awk的流程控制 流程控制语句是任何程序设计语言都不能缺少的部分。任何好的语言都有一些执行流程控制的语句。awk提供的完备的流程控制语句类似于C语言,这给我们编程带来了极大的方便。 1、BEGIN和END: 在awk 中两个特别的表达式,BEGIN和END,这两者都可用于pattern中(参考前面的awk语法),提供BEGIN和END的作用是给程序赋予初始状态和在程序结束之后执行一些扫尾的工作。任何在BEGIN之后列出的操作(在{}内)将在awk开始扫描输入之前执行,而END之后列出的操作将在扫描完全部的输入之后执行。因此,通常使用BEGIN来显示变量和预置(初始化)变量,使用END来输出最终结果。 例:累计销售文件xs中的销售金额(假设销售金额在记录的第三字段): $awk 在这里,BEGIN预置了内部变量FS(字段分隔符)和自定义变量total,同时在扫描之前显示出输出行头。而END则在扫描完成后打印出总合计。 2、流程控制语句 2.1、if...else语句: 格式: 格式中"语句1"可以是多个语句,如果你为了方便awk判断也方便你自已阅读,你最好将多个语句用{}括起来。awk分枝结构允许嵌套,其格式为: if(表达式1) 当然实际操作过程中你可能不会用到如此复杂的分枝结构,这里只是为了给出其样式罢了。 2.2、while语句 格式为: while(表达式) 2.3、do-while语句 格式为: do 2.4、for语句 格式为: for(初始表达式;终止条件;步长表达式) 在awk 的 while、do-while和for语句中允许使用break,continue语句来控制流程走向,也允许使用exit这样的语句来退出。break 中断当前正在执行的循环并跳到循环外执行下一条语句。continue从当前位置跳到循环开始处执行。对于exit的执行有两种情况:当exit语句不在 END中时,任何操作中的exit命令表现得如同到了文件尾,所有模式或操作执行将停止,END模式中的操作被执行。而出现在END中的exit将导致程序终止。 例:为了 awk中的自定义函数 定义和调用用户自己的函数是几乎每个高级语言都具有的功能,awk也不例外,但原始的awk并不提供函数功能,只有在nawk或较新的awk版本中才可以增加函数。 函数的使用包含两部分:函数的定义与函数调用。其中函数定义又包括要执行的代码(函数本身)和从主程序代码传递到该函数的临时调用。 awk函数的定义方法如下: function 函数名(参数表){ 在gawk中允许将function省略为func,但其它版本的awk不允许。函数名必须是一个合法的标志符,参数表中可以不提供参数(但在调用函数时函数名后的一对括号仍然是不可缺少的),也可以提供一个或多个参数。与C语言相似,awk的参数也是通过值来传递的。 在awk 中调用函数比较简单,其方法与C语言相似,但awk比C语言更为灵活,它不执行参数有效性检查。换句话说,在你调用函数时,可以列出比函数预计(函数定义中规定)的多或少的参数,多余的参数会被awk所忽略,而不足的参数,awk将它们置为缺省值0或空字符串,具体置为何值,将取决于参数的使用方式。 awk函数有两种返回方式:隐式返回和显式返回。当awk执行到函数的结尾时,它自动地返回到调用程序,这是函数是隐式返回的。如果需要在结束之前退出函数,可以明确地使用返回语句提前退出。方法是在函数中使用形如:return 返回值 格式的语句。 例:下面的例子演示了函数的使用。在这个示例中,定义了一个名为print_header的函数,该函数调用了两个参数FileName和PageNum, FileName参数传给函数当前使用的文件名,PageNum参数是当前页的页号。这个函数的功能是打印(显示)出当前文件的文件名,和当前页的页号。完成这个功能后,这个函数将返回下一页的页号。 nawk >#定义函数print_header 执行这个程序将显示如下内容: myfile 1 awk高级输入输出 1.读取下一条记录: awk的next语句导致awk读取下一个记录并完成模式匹配,然后立即执行相应的操作。通常它用匹配的模式执行操作中的代码。next导致这个记录的任何额外匹配模式被忽略。 2.简单地读取一条记录 awk 的 getline语句用于简单地读取一条记录。如果用户有一个数据记录类似两个物理记录,那么getline将尤其有用。它完成一般字段的分离(设置字段变量$0 FNR NF NR)。如果成功则返回1,失败则返回0(到达文件尾)。如果需简单地读取一个文件,则可以编写以下代码: 例:示例getline的使用 {while(getline==1) 也可以使getline保存输入数据在一个字段中,而不是通过使用getline variable的形式处理一般字段。当使用这种方式时,NF被置成0,FNR和NR被增值。 用户也可以使用getline<"filename"方式从一个给定的文件中输入数据,而不是从命令行所列内容输入数据。此时,getline将完成一般字段分离(设置字段变量$0和NF)。如果文件不存在,返回-1,成功,返回1,返回0表示失败。用户可以从给定文件中读取数据到一个变量中,也可以用stdin(标准输入设备)或一个包含这个文件名的变量代替filename。值得注意的是当使用这种方式时不修改FNR和NR。 另一种使用getline语句的方法是从UNIX命令接受输入,例如下面的例子: 例:示例从UNIX命令接受输入 {while("who -u"|getline) 当然,也可以使用如下形式: "command" | getline variable 3.关闭文件: awk中允许在程序中关闭一个输入或输出文件,方法是使用awk的close语句。 close("filename") filename可以是getline打开的文件(也可以是stdin,包含文件名的变量或者getline使用的确切命令)。或一个输出文件(可以是stdout,包含文件名的变量或使用管道的确切命令)。 4.输出到一个文件: awk中允许用如下方式将结果输出到一个文件: printf("hello word!\n")>"datafile" 5.输出到一个命令 awk中允许用如下方式将结果输出到一个命令: printf("hello word!\n")|"sort-t','" awk与shell script混合编程 因为awk可以作为一个shell命令使用,因此awk能与shell批处理程序很好的融合在一起,这给实现awk与shell程序的混合编程提供了可能。实现混合编程的关键是awk与shell script之间的对话,换言之,就是awk与shell script之间的信息交流:awk从shell script中获取所需的信息(通常是变量的值)、在awk中执行shell命令行、shell script将命令执行的结果送给awk处理以及shell script读取awk的执行结果等等。 1.awk读取Shell script程序变量 在awk中我们可以通过“'$变量名'”的方式读取sell scrpit程序中的变量。 例:在下面的示例中,我们将读取sell scrpit程序中的变量Name,该变量存放的是文本myfile的撰写者,awk将打印出这个人名。 $cat writename 2.将shell命令的执行结果送给awk处理 作为信息传送的一种方法,我们可以将一条shell命令的结果通过管道线(|)传递给awk处理: 例:示例awk处理shell命令的执行结果 $who -u | awk '{printf("%s正在执行%s\n",$2,$1)}' 该命令将打印出注册终端正在执行的程序名。 3.shell script程序读awk的执行结果 为了实现shell script程序读取awk执行的结果,我们可以采取一些特殊的方法,例如我们可以用变量名=`awk语句`的形式将awk执行的结果存放入一个 shell script变量。当然也可以用管道线的方法将awk执行结果传递给shell script程序处理。 例:作为传送消息的机制之一,UNIX提供了一个向其所有用户传送消息的命令wall(意思是write to all写给所有用户),该命令允许向所有工作中的用户(终端)发送消息。为此,我们可以通过一段shell批处理程序wall.shell来模拟这一程序(事实上比较老的版本中wall就是一段shell批处理程序: $cat wall.shell 在这个程序里,awk接受who -u命令的执行结果,该命令打印出所有已注册终端的信息,其中第二个字段是已注册终端的设备名,因此用awk命令析出该设备名,然后用while read tty语句循环读出这些文件名到变量(shell script变量)tty中,作为信息传送的终结地址。 4.在awk中执行shell命令行----嵌入函数system() system()是一个不适合字符或数字类型的嵌入函数,该函数的功能是处理作为参数传递给它的字符串。system对这个参数的处理就是将其作为命令处理,也就是说将其当作命令行一样加以执行。这使得用户在自己的awk程序需要时可以灵活地执行命令或脚本。 例:下面的程序将使用system嵌入函数打印用户编制好的报表文件,这个文件存放在名为myreport.txt的文件中。为简约起见,我们只列出了其END部分: . 在这个示例中,我们首先使用close语句关闭了文件myreport.txt文件,然后使用system嵌入函数将myreport.txt送入打印机打印。 写到这里,我不得不跟朋友们说再见了,实在地说,这些内容仍然是awk的初步知识,电脑永远是前进的科学,awk也不例外,本篇所能做的只是在你前行的漫漫长途中铺平一段小小开端,剩下的路还得靠你自己去走。老实说,如果本文真能给你前行的路上带来些许的方便,那本人就知足了! 如对本篇有任何疑问,请E-mail To:Chizlong@yeah.net或到主页http://chizling.yeah.net中留言。
1.awk的常规表达式元字符 \ 换码序列 2.awk算术运算符 运算符 用途 3.awk允许的测试: 操作符 含义 x==y x等于y 4.awk的操作符(按优先级升序排列) = 、+=、 -=、 *= 、/= 、 %= 5.awk内置变量(预定义变量) 说明:表中v项表示第一个支持变量的工具(下同):A=awk,N=nawk,P=POSIX awk,G=gawk V 变量 含义 缺省值 6.awk的内置函数 V 函数 用途或返回值 |
教程三,转载:http://blog.youkuaiyun.com/zg_hover/archive/2009/12/20/5044195.aspx
awk教程 awk的基本功能是对文件进行指定规则浏览和抽取信息。 基本格式: (1) awk [-F 分隔域] 'command' input-file(s) (2) 写入shell脚本中 (3) awk -f awk-script-file input-file(s) 注意:这里如果使用if等编程语句,要用{}括起来。 test name grade score id hover 2 96 2003073 twq 3 91 2003074 zsm 4 92 2003075 hzm 5 95 2003076 bl 6 96 2003077 1,文本过滤处理: (1) awk '{print $0}' test #打印文件的全部内容 注意:这里awk使用函数print用来打印整个文件的内容。其中的$0就表示整个文件的内容。 (2) awk '{print $1}' test #抽取文件test中的第一列 注意:如果awk没有使用-F指定分隔符号,默认的分隔符号是空格和TAB键。 #列出所有的用户名和登陆的shell名 awk -F : '{print $1,$6}' /etc/passwd (3) awk -F : '$1=="root" {print $0}' /etc/passwd 指打印用户名为root的那一行 2,文本格式定制 (1)给输出信息加上表头 awk -F : 'BEGIN {print "name shell\n--------------------------------"} {print $!"\t"$6}' /etc/passwd (2) awk -F : 'BEGIN {print "name shell\n--------------------------------"} {print $!"\t"$6} END {"end-of-report"}' /etc/passwd 3,在awk中使用正则表达式 ^ 表示匹配行首的字符 [...] 匹配[]正的任意一个字符 (str1|str2) 匹配含有str1或str2的行 . 匹配任意一个字符 (1)匹配 为使一域匹配一正则表达式,可以使用以下两种方法: 1)$n~正则表达式 2)if($n~正则表示式) print $0 awk -F: '$0 ~ /^root/' /etc/passwd #打印以root开头的行 awk -F: '{if($0 ~ /^root/) print $0}' /etc/passwd #和上一句等效 *精确匹配* #打印名字为root的用户在/etc/passwd文件中的记录 awk -F : '$1=="root" {print $0}' /etc/passwd #打印路径为/root的用户在/etc/passwd中的记录 awk -F : '$6=="\/root" {print $0}' /etc/passwd 4,在awk中使用条件操作符 < 小于 >= 大于等于 <= 小于等于 ~ 匹配正则表达式 == 等于 !~ 不匹配正则表达式 != 不等于 (1)模糊匹配 i)使用if {if($1~/zhengxh/) print $0} ii)不用if '$0 ~ /zhengxh/' ex: awk '$0~/zhengxh/' filename 或awk '{if($0~/zhengxh/) print $0} filename #输出含有zhengxh的行 或awk '/zhengxh/' filename (2)精确匹配 $n=="chars" awk '$1=="zhengxh" {print $0}' filename #输出第一列等于zhengxh的行 (3)反向匹配 $n !~ /adf/ awk '$1 !~ /zhengxh/ {print $0}' filename #输出第一列不是zhengxh的行 (4)大小写匹配 awk '/[zZ]hengxh/' filename #匹配含有zhengxh 或是Zhengxh的字符串
(5)使用或运算 awk '$0 ~ /(zhengxh|hover)/' filename #查找含有zhengxh或hover字串的行 或awk '{if($0~/zhengxh/ OR $0~/hover/) print $0}' filename (6)内置变量 ARGC 命令行参数个数 ARGV 命令行参数排列 ENVIRON 环境变量支持队列的 FNR 浏览文件的记录数 FS 设置输入域分隔符,与-F同 NF 记录域的个数 NR 已读的记录数 OFS 输出域分隔符 ORS 输出记录分隔符 RS 控制记录分隔符 awk 的具体运用(FAQ) * 把一个文件中满足条件的放到一个文件不满足条件的放到另一个文件 awk -F: '{if(NF==6) print $0 > "yes" else print $0 > "no" }' filename *如何在awk中使用变量 要注意的是在awk中的表达式一般是用''号括起来的,在shell中单引号是全屏蔽符,所以用单引号使得变量无法生效,在使用shell变量时,可以这样使用 ########################## #/bin/sh # name="zhengxh" count=`awk -F: ' /'${name}'/{ #这里需要使用变量的地方把变量隔开 sum+=$3 }
END { print sum } '` *使用awk输出文件的倒数第N行 tail -n $N $filename | awk '{if(NR==1) print $0}' *)如何在AWK中使用外部变量 1)aa="aaaaaaa" awk '{print "'"${aa}"'"}' $filename 2) 以下使用外部变量时有错: #!/bin/bash filepath=/etc/passwd user=root result=`awk -F":" '/$user/ { print $1}' $filepath` echo $result $ 改正: awk -F':' '/'"$user"'/{print $1}' $filepath *如何把AWK中的值,传送到外部的SHELL变量 使用$() 或 `` aa=`awk -F: '{print $0}' $filename` *进行统计 文件aa.txt 一个用户可能有多个记录,这时只统计一次: 数据 用户ID 下载文件名称 用户所在地 等。。。。。 20071128,0001,1,null,600571021800,028 20071128,0002,1,null,600571001800,021 20071128,0002,1,null,600571001802,021 20071128,0003,1,null,600571031800,020 20071128,0004,1,null,600571001800,010 统计各个的号码(最后一个字段)数量 awk -F, '{if(!b[$2$6]){a[$6]++;b[$2$6]++}}END{for(i in a){print i,a[i]}}' *如何把多个语句放在一句话(一行)中处理 cat "$file" | awk '{ip=$1; i=index($0,"\google"); if(i>1){ua = substr($0,i); print ip "\t" ua}}' *把记录 aa,bb,cc [name, address, age] 变成记录 ip,aa,bb,cc [ip,name,address,age] awk -F, '{pirntf "\"192.168.5.154\","$0}' *取一个字符串的首字母 str=abc echo ${str:0:1} echo $str|awk '{print substr($0,1,1)}' echo $str|sed 's/\(.\).*/\1/' *如何在一字符串的前面加上字符串 addtext awk '{print "addtext \""$0"\""}' temp *计算不重复的列的总和 aa|001|23 ac|001|23 bb|002|213 cc|004|32 dd|005|34 awk -F'|' '!a[$1]++{sum+=$3} END{print sum} ' filename *定义多个分界符 aa cc dd bb,ee ff awk -F'[ ,]' '{print $3}' filename 有时候有可能出现多个分隔符号,但是我们需要把它当成一个,这时就要用: *** #echo "adf::adf:f" | awk -F'[:]+' '{print $2}' #adf *** #echo "adf::adf:f" | awk -F':' '{print $2}' # #输出空 *** *如何用awk处理这样的文件格式? 源文件格式:
表1313 客户经理业绩情况表(月报表) 支局所名称:XXXX储蓄所 月份:10 客户经理 业绩(累计日积数) 酬金 姓名 代号 活期 整整3月 整整6月 整整1年 整整2年 整整3年 整整5年 整整8年 零整1年 零整3年 零整5年 定活两便 兰 37040576 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 21340.00 0.00 0.00 禚树征 37040585 27277.21 120.00 0.00 2965.22 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 845615151469035520.00 秦 37040502 20094.30 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 622937933443235840.00 合 计 444868.41 0.00 0.00 2965.22 0.00 0.00 10764.20 0.00 0.00 0.00 0.00 18600.00 13791245122257916000.00 如何用awk处理成以下格式(只要里面的记录并用逗号分割每个字段,最后一个字段不要,表头和表尾不要): "兰",37040576,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,21340.00,0.00 "禚树征",37040585,27277.21,120.00,0.00,2965.22,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00 "秦",37040502,20094.30,0.00,0.00,0.00,0.00,0.00,,0.00,0.00,0.00,0.00,0.00,0.00 awk '{sub("[ \t]", ","); print $0}' temp awk '{sub("[ ,\t]", ","); print $0}' temp *如何用TAB做分隔符号 awk -F'\t' awk -F'[ \t]' #默认是这样,以空格或TAB做分隔符 一般模式:awk -F'rexp' '{}' filename 这里rexp是一个正则表达式,用来指示要使用的分隔符。 *-------------------------- 在awk脚本中有下面一段 BEGIN{split("123#456#789",team,"#")} END{for(i in team) print team} 预测的输出应该是 123 456 789 啊! 为什么实际的输出是 456 789 123 呢? 答: --- while(++i in team) print team[i] ---------------------------- *-awk中使用system() answer: ls | awk '{if (system("ls " $0) == 0) {print "file " $0 " exists !"}}' *-调用外部命令和awk结合 使用getline得到外部命令的输入f ls | awk '{getline ll; print $ll}' -------------------------- *-只输出第一行的内容 awk '{print; exit}' *-多shell命令 awk ’BEGIN{while("dir|sed 1,3!d"|getline)print $1}‘ *-在awk的输出中加单引号 #cat file rwxrwsrwx gprs 512 GPRS awk '{printf("%s %s '"'%s'"' %s\n",$1,$2,$3,$4)}' file 在这里要理解的是:上面的表达式分成了三块,前面的''内的内容是一块,中间的双引号内的内容是一块,最后的单引号里的内容是一块;由于单引号在双引号中的作用被屏蔽,所以输出的变量会 带上单引号。从而达到预定结果。 *-得到df -h 显示出来的百分数字(去掉百分号) (1)df -h | awk '{if(NR!=1) print $5}' | cut -d% -f 1 (2)df -h | awk -F'[ \t%]+' '{if(NR!=1) print $5}' *** 实现加和 中间结果如下所示: CPU usr sys idl 0 13 4 76 1 9 4 79 要想显示下列结果: 1 22 8 155 *** cat data | awk '{if(NR!=1) a+=$1;b+=$2;c+=$3} END{print a,b,c,d,e}' *** 如何实现以几个字母中任意一个打头的字符串的查找 cat data Mike Harrington:(510) 548-1278:250:100:175 Christian Dobbins:(408) 538-2358:155:90:201 Susan Dalsass:(206) 654-6279:250:60:50 Archie McNichol:(206) 548-1348:250:100:175 Jody Savage:(206) 548-1278:15:188:150 Guy Quigley:(916) 343-6410:250:100:175 Dan Savage:(406) 298-7744:450:300:275 Nancy McNeil:(206) 548-1278:250:80:75 John Goldenrod:(916) 348-4278:250:100:175 Chet Main:(510) 548-5258:50:95:135 Tom Savage:(408) 926-3456:250:168:200 Elizabeth Stachelin:(916) 440-1763:175:75:300 awk -F'[ :]' '$1~/^[MJ] {print $1}' 输出以D开头的域 awk -F':' '{for(i=1;i<=NF;i++) if($i~/^D/) print $i}' data2 ****每一行的和 统计 #cat ab a 1 a 2 b 2 awk '{a[$1]+=$2} END{for(i in a) print i,a[i]}' file ----------------------------------- *对两个文件的处理 ---------- 大家好,想请教一个问题,我现在有两个文件,如下所示,这两个文件格式都是一样的。我想首先把文件2的第五列删除,然后用文件2的第一列减去文件一的第一列,把所得的结果对应的贴到原来第五 列的位置,请问这个脚本该怎么编写? file1: 50.481 64.634 40.573 1.00 0.00 51.877 65.004 40.226 1.00 0.00 52.258 64.681 39.113 1.00 0.00 52.418 65.846 40.925 1.00 0.00 49.515 65.641 40.554 1.00 0.00 49.802 66.666 40.358 1.00 0.00 48.176 65.344 40.766 1.00 0.00 47.428 66.127 40.732 1.00 0.00 51.087 62.165 40.940 1.00 0.00 52.289 62.334 40.897 1.00 0.00 file2: 48.420 62.001 41.252 1.00 0.00 45.555 61.598 41.361 1.00 0.00 45.815 61.402 40.325 1.00 0.00 44.873 60.641 42.111 1.00 0.00 44.617 59.688 41.648 1.00 0.00 44.500 60.911 43.433 1.00 0.00 43.691 59.887 44.228 1.00 0.00 43.980 58.629 43.859 1.00 0.00 42.372 60.069 44.032 1.00 0.00 43.914 59.977 45.551 1.00 0.00 --答-- awk 'NR==FNR{a[NR]=$1}NR!=FNR{$5=a[FNR]-$1;print}' file2 file1 说明: 当NR==FNR时,是第一个文件,到了第二个文件时FNR会从0开始计数,而NR却继续在原来的基础上自增。 先把第一个文件中要使用的内容保存到一个数组中,然后在处理第二个文件时才使用。 这里包含了很好的处理多个文件的方法,值得借鉴。 ------------------------------------------------- ** 源文件如下: 37123456,123456789,601234020200051640,"孔霞","03",123456789,"2008/01/06",1,4000,5060.41 37123456,123456789,601234020200062521,"栗汝礼","03",123456010,"2008/01/06",1,100,110.91 37123456,123456789,601234020200069800,"柯纯龙","03",370786017,"2008/01/06",1,20000,19500 37123456,123456789,601234020200069800,"柯纯龙","03",123456030,"2008/01/06",1,31000,500 37123456,123456789,601234020200068018,"严凤书","03",123456789,"2008/01/06",2,50000,100163.39 37123456,123456789,601234020200070039,"刘庆","03",123456789,"2008/01/06",2,4000,8000 37123456,123456789,601234020200060554,"王兰英","03",123456789,"2008/01/06",1,1600,91.26 37123456,123456789,601234020200070039,"刘庆","03",123456789,"2008/01/06",2,4000,4000 37123456,123456789,601234020200067710,"罗有艳","03",123456789,"2008/01/06",2,3000,12012.01 37123456,123456789,601234020200064742,"孙祥婷","03",123456789,"2008/01/06",1,50,12.61 37123456,123456789,601234020200069800,"柯纯龙","03",123456030,"2008/01/06",1,200,300 37123456,123456789,601234020200060554,"王兰英","03",123456789,"2008/01/06",1,1000,1091.26 处理要求如下: 如果第三列中的数据是唯一的,就保留这一行,如果有重复的,就保留最后一个记录行。 --------答--------- awk -F, '{a[$3]=$0}END{for( i in a)print a[i]}' urfile ------------------------------ *如何快速获取特定字符串的前2(n)行和后2(n)行 $cat file put 8 put 9 put 10 abc put 11 put 12 put 13 put 14 abc put 15 put 16 put 17 put 18 abc put 19 put 20 put 21 put 22 put 23 abc put 24 put 25 put 26 put 27 abc put 28 put 29 put 30 put 31 put 32 abc put 33 put 34 put 35 put 36 put 37 $ awk '{a[NR]=$0}/abc/{for(i=2;i>=0;i--) print a[NR-i];for(j=1;j<=2;j++){if(!getline) exit;print}print ""}' urfile 小结: (1)这里使用了数组的功能,数组在作为缓存是普遍用法,要记住。 但这里如果文件超大的话,缓冲区的负担太大,应换存自己需要的哪些行(这里我只换存了4行) $ awk '{a[NR%4]=$0}/abc/{for(i=2;i>=0;i--) print a[(NR-i)%4];for(j=1;j<=2;j++){if(!getline) exit;print}print ""}' urfile (2)使用了getline函数-- $ man awk 就知道,getline函数的作用是: 1)读取下一行2)set $0 注意这两个元素的应用. *)如何提取aaaa12123adsf adfadfbbbb 的aaaa和bbbb中间的内容 $cat file adfaaaaadfadfadfdfadabbbb adfaaaaadf ad323452 adfadfdfadabbbbz $ 1)sed -e 's/.*\(aaaa\)\(.*\)\(bbbb\).*/\2/g' file 2)sed -e 's/.*\(a\{3\}\)\(.*\)\(b\{3\}\).*/\2/g' file 3)echo "aaaa121312dfadfbbbbb" | awk -F'aaaa|bbbb' '{print $2}' *)我以如下字符要处理 a 123 b 124 c 125 a 126 d 127 e 128 ac 129 如果第一列出现两次或两次以上将其打印出来,并计算出现次数。 $ awk '{a[$1]++;} END{for(i in a) if(a[i]>=2) {print i,a[i]}}' file 分析: 由以上的命令可以得到流程: a["a"] 2 a["b"] 1 a["c"] 1 a["d"] 1 a["e"] 1 a["ac"] 1 而for(i in a) 则是要遍历的i的值是:a,b,c,d,e,ac *)去掉重复的行 awk '!a[$0]++' file *)去掉重复行,并保持顺序不变 awk 'f[$0]!=1{print;f[$0]=1}' *)打印重复行 1)awk '{a[$0]++} END{for(i in a) {if(a[i]>1){print i}}}' filename 2)sort cc | uniq -dc *)如何匹配多个模式 1)awk '/p1|p2/' file 2)awk '/zhengxh|\<root\>' file *)设定字段分隔符 1)awk -F':' '{OFS="-"}{print $1,$2,$3}' file *)范围查找 1)awk -F':' '/20080501[2-9]/' file *)数字计算求和 file: hammers QTY: 5 PRICE: 7.99 TOTAL: 39.95 drills QTY: 2 PRICE: 29.99 TOTAL: 59.98 punches QTY: 7 PRICE: 3.59 TOTAL: 25.13 drifts QTY: 2 PRICE: 4.09 TOTAL: 8.18 bits QTY: 55 PRICE: 1.19 TOTAL: 65.45 saws QTY: 123 PRICE: 14.99 TOTAL: 1843.77 nails QTY: 800 PRICE: .19 TOTAL: 152 screws QTY: 80 PRICE: .29 TOTAL: 23.2 brads QTY: 100 PRICE: .24 TOTAL: 24 1)awk '{x=x+$2}' file *) --- 3 0.022913642968727541 2 0.022706007307485104 2 0.50444767354650166 3 0.022128299612739447 6 0.025468440060252208 1 0.022856042968727539 第一列相同则第二列对应值求和。。。输出$1,sum --- 1)awk '{a[$1]=+$2; b["2"$1]++} END{for(i in a) if(b["2"i]>1) print i,a[i]}' file *)我以如下字符要处理 a 123 b 124 c 125 a 126 d 127 e 128 ac 129 如果第一列出现 两次或两次以上 将其打印出来,并计算出现次数。 1)awk '{a[$1]++} END{for(i in a) print i,a[i]}' file ------ *)awk中如何显示大数据 1)awk '{printf"%.f\n", NR + 1211439408282}' filename *)awk使用外部变量 1)awk '{if($3=="'$a'") print $1,$2,"'$b'",$4}' text 2)awk '{if($3=='\"$a\"') print $1,$2,'\"$b\"',$4}' text *) 文件内容: 74683 1001 74683 1002 74683 1011 74684 1000 74684 1001 74684 1002 74685 1001 74685 1011 74686 1000 .... 100085 1000 100085 1001 文件就两列,希望处理成 74683 1001 1002 1011 74684 1000 1001 1002 ... 就是只要第一列数字相同, 就把他们的第二列放一行上,中间空格分开 -------------- 1) awk '{a[$1]=sprintf("%s %s", a[$1],$2)} END{for(i in a) print i,a[i]}' file 2) awk '{a[$1]=a[$1]" "$2} END{for(i in a)print i,a[i]}' data13 *) 76523 1001 1002 76524 1002 1003 76526 1000 1003 76528 1000 .... 100025 1000 1025 请教下, 文件第一列已按大小排序, 现在想按第一列的顺序, 把没有出现的行数补上 实现 76523 1001 1002 76524 1002 1003 76525 76526 1000 1003 76527 76528 1000 .... 100025 1000 1025 怎样能够直接补上这些缺失的行 ------------------- 1)??????? *) 每个字段形如 <data name="CYRSBH" value="320400725220211"/>,如何高效的提取value="*****"中间的*** 望各位不吝赐教 ------------- 1) grep -o "value=.*\"" data7 | awk -F'"' '{print $2}' 2) sed 's/.*value="\(.*\)".*/\1/' file *) --- 两个文件 a b #cat a a1 b=1 num=3 c=2 a3 b=1 num=3 c=3 bc f=3 num =2 f=3 fa f=4 num=2 f=6 #cat b a4 b=1 num=6 c=3 a1 b=1 num=5 c=2 bc f=3 num =1 f=3 fb f=4 num=3 f=6 要求对比两个文件 条件1:如果文件a中有和文件b第1,2,4部分都相同的行则用文件b中该行的第三部分num=x 其x的值减去文件a中该行第三部分num=x其x的值,并将结果连同该行的其他部分写入文件c 例如: 文件b中第二行a1 b=1 num=5 c=2的第一部分:a1 ,第二部分b=1,第4部分c=2和文件a的第一行a1 b=1 num=3 c=2相应部分相同则将结果 a1 b=1 num=2 c=2 写入文件c (num=2是文件b的num=5减去文件a的num=3的得来的) 条件2:如果条件1中num后数值相减后该结果为负值则将文件b中的该行直接写入文件c 例如:b中的第三行bc f=3 num =1 f=3与文件a中的第三行bc f=3 num =2 f=3的1,2,4部分相同,但是num后数值的运算结果为-1 (1减2得来的)所以直接将文件b中的该行bc f=3 num =1 f=3直接计入文件c 条件3:如果文件a中没有找到和文件b中1,2,4部分相同的行则将文件b中的该行直接写入文件c 例如:文件b的第四行fb f=4 num=3 f=6,在文件a中无法找到和他第1,2,4部分相同的行所以直接将该行写入文件写入文件c 条件4:a或者b本文本身中不会出现第1,2,4部分相同的行 --- test.awk #!/bin/awk -f NR==FNR { sub(/.*=/ ,"" ,$3) h[$1$2$4] = $3 } NR>FNR { i = 0 sub(/.*=/, "" ,$3) if($1$2$4 in h) { i = $3 - h[$1$2$4] } if(i>0) $3 = "num="i else $3 = "num="$3 } awk -f test.awk a b > c *)awk对文件进行分流 $cat file: 00:49:42.025791 14058101005 2008-05-31 09:41:2 -00:00:34.974209 14058101003 2008-05-31 10:31:4 ... 目的是把以00开头的行输出到一个文件,-00开头的行输出到一个文件,用一条awk语句可以实现么? *) 如何在文件中使用awk设定的变量 参考: #awk -v min=43922 -v max=52059 '{a[$1]}END{for(i=min;i<=max;i++)if(!(i in a))print i}' *) 3 0.022913642968727541 2 0.022706007307485104 2 0.50444767354650166 3 0.022128299612739447 6 0.025468440060252208 1 0.022856042968727539 。。。 第一列相同则第二列对应值求和。。。输出$1,sum 这样的是错误的!!! #awk 'a[$1]+=$2; END{for(i in a) print i,a[i]}' cata3 right : awk '{a[$1]+=$2} END{for(i in a) print i,a[i]}' cata3 *) 有一个类似于这样的文本: 16 001agdcdafasd 16 002agdcxxxxxx 23 001adfadfahoh 23 001fsdadggggg 我想要得到 16 001 16 002 23 001 23 002 在awk中,就是取$2的前三个字符,但是不知道如何处理 大家帮帮忙哦,先谢谢了:) ---- 1)awk '{print $1,substr($2,1,3)}' 2)sed 's/\(.* ...\).*/\1/' file 3)grep -o '^.\+ \+...' file *)把文件 file CHN0401 部门1组 分部门查询 吴斌 CHN0402 部门2组 查询 李演 CHN0403 部门3组 查询 李路 变为 ------------------------------------------- CHN0401 部门1组 分部门查询 吴斌 CHN0402 部门2组 查询 李演 CHN0403 部门3组 查询 李路 1) awk '/CHN/{h=$1; sub("\n","",h); printf "%s ",h; for(i=0; i<=3; i++) {if(getline var) { sub("\n","",var);} var=sprintf("%s ", var); printf "%s",var; }print "";}' file 2) $cat ff.awk #!/bin/awk -f # /CHN/{ h=$1; sub("\n","",h); printf "%s ",h; for(i=0; i<=3; i++) { if(getline var) { sub("\n","",var); } var=sprintf("%s ", var); printf "%s",var; } print ""; } file $ff.awk filename 或 #!/bin/awk -f # /CHN/{ s=$0; for(i=0; i<=3; i++) { getline s=sprintf("%s %s", s,$0); } printf "%s", s; print ""; } file *替换特定行之间的行 *) 替换注释行<!-- --> <!-- <mapping resource="0.xml" />--> <mapping resource="1.xml" /> <mapping resource="2.xml" /> <!-- <mapping resource="3.xml" /> --> <mapping resource="4.xml" /> <!-- <mapping resource="5.xml" /> --> <!-- <mapping resource="6.xml" />--> <mapping resource="7.xml" /> 1)awk 'BEGIN{RS="<!--|-->"}NR%2' urfile *)使用多个单词作为分隔符 awk -F'word1|word2' '{print $3}' *) 把不同的结果定向到不同的文件中去 有这样个文件 123|0|444 123|1.00|444 588|222|333 现在想把第2个字段为0的取出来输出到一个文件,并删除该记录,用awk如何实现,谢谢 代码如下: ----------------------------------------------- [zhengxh@hoverzg stdshell]$ cat dd 123|0|444 123|1.00|444 588|222|333 #注意在输出的文件名前面要加双引号 [zhengxh@hoverzg stdshell]$ awk -F'|' '{if($2==0)print >"file1"; else print >"file2"}' dd [zhengxh@hoverzg stdshell]$ cat file1 123|0|444 [zhengxh@hoverzg stdshell]$ cat file2 123|1.00|444 588|222|333 ----------------------------------------------- *) 比如解析下面一行: 123||name||address||age 我想以“||”为分割符,这样各个域为“123”, “name”,“age” 1)awk -F"[|]+" '{print $1}' filename *)单引号的输出 1) awk 'BEGIN{print "'\'看我的\''";}' *)找出不含指定字符串的行 awk '!(/abc/||/def/) 找出不含abc或者不含def的列作为条件 ----------------------------------------------- [zhengxh@hoverzg stdshell]$ awk '!(/dd/||/1/) {print }' dd 588||222||333 [zhengxh@hoverzg stdshell]$ cat dd 123||0||444 123||1.00||444 588||222||333 ----------------------------------------------- *)只处理最后一行 1)awk 'END{ print $0}' test 2)tail -1 | awk ... *)只是处理第一行 1) awk '{print $0; exit}' filename 2) head -1 file | awk ... *)处理文件中指定的n行 1) awk '{if(NR==n) print }' 2) head -n | tail -m | awk ... *) 某个文本文件,当逐行读取时,当发现第一个字段是空格或空值时(cut -d' ' -f1),就将所在行与上行合并。 1)awk '/^[^ \t]/{printf "\n"$0}; /^[ \t]/{printf $0}END{printf "\n"}' file 1*) awk 'BEGIN{getline;printf $0}/^[^ \t]/{printf "\n"$0};\ /^[ \t]/{printf $0}END{printf "\n"}' urfile #注意如果用print是不能实现的,因为print 会打印一个\n 解释: 如果前面的字符不是空格就打印一个\n,再打印这一行, 如果是就直接打印但不换行 2)sed ':a;N;/\n[[:blank:]]\+/{s/\n//;ba};P;D' 数据文件 解释: :a 设置跳转标签 N 读入下一行 /\n[[:blank:]]\+/{s/\n//;ba} 如果下一行是以空白开头的话,就把换行符删除, 然后再读取下一行,直到读取到不是以空白开头的行 P; 打印第一个换行符之前的内容 D; 删除第一个换行符之前的内容,并重新开始循环 *) 有个文件格式如下: aaa bbb ccc yyyuu jjjkkk sss aaa ccc 。。。。 有重复的字符串,要求对每个不一样的字符串计数并按计数的降序排列输出。输出的文件就只有各个不一样的字符串而已。 sort b | uniq -c | sort *) $ cat file DAA= 123413 ZZASDF DAA= 123413 ZZASDF DAA= 123413 ZZASDF $ awk 'BEGIN{RS="DAA="} {gsub(/[^\n]/,"9",$0); if(length($0)>0) printf "%s %s",RS,$0}' file *) ----------------------- 各位大牛好: 小的有这样两个文件,记录不同查询出来的次数。 文件一 a.txt,有两个字段,一个是次数,一个是pid,具体如下: 2 CC214798313J90000000000 1 CC214798119J90000006000 1 CC214790518J90000001000 1 CC214790518 1 CC214788013J90000005000 1 CC214788013 1 CC214783814J90000003000 1 CC214783814J90000002000 1 CC214783814 1 CC214778610 文件二,b.txt ,也有两个字段,一个是次数,一个是pid,具体如下: 1 CC153301918J90000010000_765 1 CC120143642J90000043000_765 1 CC000024062J90033095000_765 1 CC000001583J90000044000_765 1 CC000001583J90000046000_768 1 CC130012773J90000076000_765 1 CC130012773J90000063000_765 1 CC130012773J90000064000_765 1 CC130012773J90000051000_765 1 CC130012773J90000052000_765 1 CC138037658J90000044000_538 这两个文件记录的pid是可能相同的,我想把这两个文件组成一个文件: 次数1 次数2 pid 2 0 CC214798313J90000000000 1 0 CC214798119J90000006000 也就是合并两个文件中的两个字段 ,组成三个字段的第三个文件。 请假兄弟姐妹们。谢谢 -- *在指定行插入一行 awk '1;NR==1{print "addadf"}' file ----------------------------------------- *awk能实现对一个文件进行不同条件的匹配,然后按匹配的不同输出不同的文件吗?? 比如这样的文件: ##a1a1a1a1 b1: @c1c1c1c1c1 d1: %e1e1e1e1 ##a2a2a2 b2: @c2c2c2c2 d2: %e2e2e2e2 将满足#开头的记录输出的a文件,将@开头的记录输出的b文件,将%的文件输出到c文件 所有操作希望通过一个脚本文件实现 这样条件我都知道怎么去配置就是不知道怎么按条件的不同输出啊,awk脚本能实现,如果不能怎么去实现它呢。 希望大侠们指教呢 do: awk 'BEGIN{FS="";a["#"]="a";a["@"]="b";a["%"]="c"}($1 in a){print > a[$1]".txt"}' urfile awk 'BEGIN{FS="";a["#"]="a";a["@"]="b";a["%"]="c"}($1 in a){print > a[$1]".txt"}' urfile 本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/zg_hover/archive/2009/12/20/5044195.aspx |