awk的使用及字符串的操作

2023-05-16

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
        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

 

 

 

 

 

 

 

 

 

 

 

 

2008-12-15 18:443621人阅读评论(0)收藏举报

#!/bin/bash

##########################################
#
#   演示bash中操作字符串的操作
#
#   后面是输出结果
#
##########################################

str="abc123abcABC"
#    |-|
#    |-------|

#计算字符串的长度
echo ${#str}    #12

#位置参数有关操作
echo ${#*}      #位置参数的个数
echo ${#@}      #位置参数的个数和上面的效果一样
echo $*         #把所有的位置参数作为一个字符串输出
echo $@         #效果同上
#字串截取
#
#    ${string#substring}
#         从$string的左边第一个字符截掉第一个匹配的$substring
#    ${string##substring}
#         从$string的左边第一个字符截掉最后一个个匹配的$substring
#
#从左边开始
echo ${str#a*c} #a到c的最短匹配
echo ${str##a*c} #a到c的最长匹配

#从右边开始
echo ${str%a*C}     #从右边的最后一个字符开始寻找a到B的最短匹配
echo ${str%%a*B}    #从右边最后一个字符开始寻找a到B的最长匹配
                    #这里找不到模式

#==取子串==
#   ${string:position}
#   ${string:positon:length}
#
echo ${str:2}       #从第2个位置开始提取字符串的值
echo ${str:2:3}     #从第2个位置开始提取长度为3个字符的值
#反向提取子串
echo ${str:(-2)}        #从反向的第2个位置开始提取字符串
echo ${str:(-2):6}      #从反向的第2个字符的位置开始提取长度为6个字符的串(:(不可能把)
                        #总共的字符长度只有2个怎么提取6个呢呵呵
echo ${str:(-6):3}      #6个中提出3个总可以了把

#位置参数的提取

echo ${*:2}         #从第二个位置参数开始提取后面所有位置参数的值
echo ${*:2:3}           #从第二个位置参数开始提取3个位置参数的值

#=子串替换=
# ${string/substring/replacement}
#   使用$replacement来替换第一个匹配的$substring.
# ${string//substring/replacement}
#   使用$replacement来替换所有匹配的$substring.
#
# ${string/#substring/replacement}
#   如果$substring匹配$string的开头部分,那么就用$replacement来替换$substring.
# ${string/%substring/replacement}
#   如果$substring匹配$string的结尾部分,那么就用$replacement来替换$substring.
#
str1="123abcABCab12"

echo ${str1/12/hover}   #仅仅替换了第一个
echo ${str1//12/hover}  #替换了所有的

echo ${str1/#12/hover}  # 从头开始匹配12,如果找到做替换
echo ${str1/%12/hover}  # 从尾开始匹配12,如果找到做替换

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

awk的使用及字符串的操作 的相关文章

  • sed 匹配换行符中的模式

    这是我的输入
  • 将 awk 输出保存到变量 [重复]

    这个问题在这里已经有答案了 谁能帮我解决这个问题吗 我正在尝试将 awk 输出保存到变量中 variable ps ef grep port 10 grep v grep port 10 awk printf s 12 printf var
  • AWK:打印一个字段中具有最大值的所有行每个其他字段,包括具有最大值和多个列的相同行

    我很感激许多贡献者迅速提供了许多解决方案 AWK 打印一个字段中具有最大值的所有行每个其他字段 包括具有最大值的相同行 https stackoverflow com questions 75392860 awk print all row
  • 如何垂直分割250k列的文件?

    我需要根据大小 首选 或列数将 250k 的文件拆分为几个 5 块 我知道split命令用于按行拆分 但不知道是否有类似的函数用于按列拆分 我的文件中的列数不均匀 因此块不能具有相同的列数 Input AA BB CC DD EE FF G
  • bash while 循环没有按预期工作

    我知道从技术上讲 它可能会按原样工作 并且这是人们所期望的bash语言 但这不是我所期望和写的 我试图让一切尽可能简单 This is fileA Name Status Networks Image Plans HostName A PA
  • 使用 awk 仅从字符串中获取数字

    背景 我有一个专栏should以 描述文本 ref12345678 的形式获取用户输入 我有现有的脚本可以获取参考号 但不幸的是一些用户错误地添加了它 所以而不是 ref12345678 有可能 ref 12345678 RF1234567
  • awk 有条件地组合多行

    我想将多行不同长度的值合并到一行 如果它们与 ID 匹配 输入示例是 ID Value a 1 49 a 2 75 b 1 120 b 2 150 b 3 211 c 1 289 d 1 301 d 2 322 所需的输出示例是 ID Va
  • 正则表达式用 SED/AWK 替换特定列

    我的数据如下所示 制表符分隔 Organ K ClustNo Analysis LN K200 C12 Gene Ontology LN K200 C116 Gene Ontology CN K200 C2 Gene Ontology 我想
  • 在 shell 脚本中禁止输出到屏幕

    你好 我写了一个小脚本 usr bin ksh for i in DAT do awk BEGIN OFS FS 3 353 3 353861958962 print i gt gt i changed awk 3 353 i change
  • awk 计数频率

    嘿 我想统计 awk 中某一列的数据量 一个示例数据集是 2 5 8 1 3 7 8 5 9我想计算第二列中 5 的出现频率 这就是我尝试过的方法 但没有成功 total 0 for i 1 i lt NF i if i 2 if i 5
  • 从文件中读取行,在第二个文件中 grep ,并为每个 $line 输出一个文件

    我有以下两个文件 sequences txt 158333741 Acaryochloris marina MBIC11017 uid58167 158333741 432 1 432 COG0001 0 158339504 Acaryoc
  • 使用 grep 仅打印上下文

    Using grep http www computerhope com unix ugrep htm 您可以打印与您的搜索查询匹配的行 添加一个 C选项将打印两行周围的上下文 如下所示 gt grep C 2 lorem some con
  • BASH - 随机排列文件中字符串中的字符

    我有一个文件 filename txt 具有以下结构 gt line1 ABC gt line2 DEF gt line3 GHI gt line4 JKL 我想打乱字符串中的字符not开始机智 gt 输出将 例如 如下所示 gt line
  • 创建带小数秒的时间戳

    awk可以使用 strftime 函数生成时间戳 例如 awk BEGIN print strftime Y m d H M S 2019 03 26 08 50 42 但我需要一个带有小数秒的时间戳 最好是纳秒 gnu date可以用 N
  • 按行号和列号对文件进行子集化

    我们想要按行和列对文本文件进行子集化 其中行数和列数是从文件中读取的 不包括标题 第 1 行 和行名称 第 1 列 输入文件 txt制表符分隔的文本文件 header 62 9 3 54 6 1 25 1 2 3 4 5 6 96 1 1
  • 如何拆分一行并重新排列其元素?

    我在一行中有一些数据 如下所示 abc edf xyz rfg yeg udh 我想呈现如下数据 abc xyz yeg edf rfg udh 以便打印备用字段并用换行符分隔 有没有这样的衬里 下列awk脚本可以做到这一点 gt echo
  • 如何在bash中仅提取两个字符串之间多行的第一个实例?

    我的文件是 abc 123 xyz abc 675 xyz 我想提取 abc 123 xyz 123 可以是任何东西 重点是我想要第一次出现 我尝试使用这个 sed n abc xyz p filename 但这给了我所有的例子 我怎样才能
  • Bash:循环遍历字符串数组后无法读出带空格的字符串

    我正在使用循环读取数组的内容 该数组包含名为 music 的目录层次结构中的所有目录和文件 内容是 find 命令先前输出的字符串 这个想法是根据流派 艺术家和标题将 directory contents 中每个数组元素的完整目录路径分成子
  • git 别名中的 AWK 语句

    我正在尝试创建一个 git 别名来以特定格式打印日志中的所有拉取请求 但是 我在使用 AWK 删除双空格时遇到问题 这是使用以下命令的 git log 的输出 git log merges grep pull request pretty
  • 用于计算数据文件中数字列表的平均值的脚本

    文件data txt包含以下内容 1 00 1 23 54 4 213 2 3 4 脚本的输出应该是 ave 54 646 一些简单的脚本是首选 这是一种方法 awk s 1 END print ave s NR RS file ave 5

随机推荐

  • 编程常用英语词汇大全

    编程常用英语词汇大全 很实用的编程英语词库 xff0c 共收录一千五百余条词汇 第一部分 xff1a application 应用程式 应用 应用程序 application framework 应用程式框架 应用框架 应用程序框架 arc
  • [LTMP搭建] Centos 6.5 安装配置 Tengine

    接上篇 xff1a http www cnblogs com antarctican p 3752812 html 安装PHP 一 安装依赖的扩展 记得前几天编译tengine xff0c 不使用 with http lua module
  • .net项目移植后的虚拟目录的配置问题

    VS NET 2003 开发环境打开此项目 xff08 MyWeb xff09 时 xff0c 出现如果如下问题 xff1a 无法从 Web 服务器获取项目文件 无法打开 Web 项目 MyWeb 文件路径 C Inetpub wwwroo
  • JS 柯里化 (curry)

    用 JS 理解柯里化 函数式编程风格 xff0c 试图以函数作为参数传递 xff08 回调 xff09 和无副作用的返回函数 xff08 修改程序的状态 xff09 很多语言采用了这种编程风格 JavaScript xff0c Haskel
  • C语言头文件编程,C语言编程规范-头文件(Day2)

    1 头文件 背景 对于C语言来说 xff0c 头文件的设计体现了大部分的系统设计 不合理的头文件布局是编译时间过长的根本原因 xff0c 不合理的头文件实际上是不合理的设计 术语定义 依赖 xff1a 本章节特指编译依赖 若x h包含y h
  • Win10共享打印机所需要的设置(无需密码访问实现打印机共享,共享不要密码)...

    原文 xff1a https m baidu com from 61 1086k bd page type 61 1 ssid 61 0 uid 61 0 pu 61 usm 64 0 sz 64 1320 1002 ta 64 iphon
  • RBF神经网络的matlab简单实现

    径向基神经网络 1 径向基函数 Radial Basis Function xff0c RBF 神经网络是一种性能良好的前向网络 xff0c 具有最佳逼近 训练简洁 学习收敛速度快以及克服局部最小值问题的性能 xff0c 目前已经证明径向基
  • npm不是以管理身份运行遇到的问题

    环境 win10 43 npm3 10 5 问题 在npm install lodash时 出现下列错误 34 npm debug log 34 文件内容 0 info it worked if it ends with ok 1 verb
  • JSON_VALUE

    本页目录 语法入参功能描述示例 语法 span class pln style color rgb 0 0 0 VARCHAR JSON VALUE span span class pun style color rgb 102 102 0
  • 浮点数的表示方法

    计算机中浮点数的表示 never2die 长江大学湖北荆州 中文摘要 xff1a 本文介绍了浮点数在计算机中的几种表示方法 xff0c 并对此进行整理分析 xff0c 为人们以后做此方面的研究提供参考 中文关键词 xff1a 浮点数 xff
  • matlab 中atan2函数的介绍

    atan2 a b 是4象限反正切 xff0c 它的取值不仅取决于正切值a b xff0c 还取决于点 b a 落入哪个象限 xff1a 当点 b a 落入第一象限时 xff0c atan2 a b 的范围是 0 pi 2 当点 b a 落
  • 研究生毕业入职阿里,2年升职到P7,晒出真实月薪,以为看错了

    互联网企业已经成为现在大部分年轻人选择职业打拼的行业 xff0c 这个行业机会多 xff0c 有各种各样的职位和机会留给优秀的年轻人去闯 xff0c 但是相应的压力也非常大 毕竟高薪水的待遇下 xff0c 工作压力又怎么会轻松的了呢 xff
  • mac清理软件哪个好用?五大Mac Cleaner介绍推荐

    还在找好用的Mac清理软件吗 xff1f 你的Mac变慢了吗 xff1f 如果给你的Mac安装一款Mac清理软件 xff0c 可以删除Mac中不需要的垃圾文件 xff0c 以释放Mac的磁盘空间和内存 不知道mac清理软件哪个好用 xff1
  • 解决"SSL handshake failed"问题

    前阵子不知是对Ubuntu动了些啥 xff0c 结果Ubuntu One死活也不上 App Center上点击 34 Buy 34 按钮会提示 34 SSL handshake failed 34 猜想大概是由于同一问题导致的 网上给出的解
  • 当在Win8下安装msi类型的文件出现errorcode 2503的解决方法

    Win8安装程序出现2502 2503错误解决方法 在Win8中 xff0c 在安装msi安装包的时候常常会出现代码为2502 2503的错误 其实这种错误是由于安装权限不足造成的 xff0c 可以这种msi的安装包不像其他exe的安装程序
  • 极限编程实践

    摘自 xff1a 敏捷软件开发 xff1a 原则 模式与实践 Robert C Martin 著 xff0c 邓辉 译 极限编程实践 xff1a 1 完整团队 XP项目的所有参与者 xff08 开发人员 业务分析师 测试人员等等 xff09
  • keil5c语言定义引脚,keil编写C程序是不是不能在函数内定义变量啊,求大神

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 肯定可以的 xff1a 比如 程序动态显示字符 显示光标和光标闪烁打开效果 include 包含头文件 xff0c 义 include sbit RS 61 P2 4 定义端口 sbit RW
  • CircleProgressBar

    今天又写了一个demo xff0c 带有两个进度值的 圆环进度条 xff0c 原谅我是个小白 xff0c 只能写一写简单的自定义控件 xff0c 我会继续努力的 先看效果图 001 gif lt pre gt 64 Override pro
  • c++采集声卡输出_手机直播声卡转换器的分析与选购

    时下直播行业非常火爆 xff0c 相关周边产品五花八门 xff0c 良莠不齐 今天为大家带来的这篇长文 xff0c 旨在为选购设备苦恼的朋友提供帮助 闲话少叙 xff0c 开始正题 目前大家的使用的直播设备基本分为以下两种形式 xff1a
  • awk的使用及字符串的操作

    awk教程 awk的基本功能是对文件进行指定规则浏览和抽取信息 基本格式 xff1a 1 awk F 分隔域 39 command 39 input file s 2 写入shell脚本中 3 awk f awk script file i