您的位置:首页 > 其它

awk 教程及使用问答

2016-01-14 13:54 281 查看
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

print

}

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: