不知道csdn不能直接黏贴图片所以,想看图片的,直接在上面地址可以看
awk是一个快捷脚本
首先我们先认识hello_word吧
$ echo "hello_world" | awk '{print $0}'
hello_world
一 、怎么调用awk
1. 命令行形式
cat test |awk '{print $0}'
awk '{print $0}' test
两种形式都可以
2. shell脚本 shell脚本是是awk命令
创建一个shell脚本 我弄的是awk.sh 内容如下:
#!/bin/bash
awk '{print $0}' $*
3. 单独弄个awk脚本 里面不包含awk这个就是纯‘{}’里面的内容
里面的内容必须加大括号
{print $0}
这里建议做成shell或者单独弄个文件,避免重复工作
二.awk结构
awk 【参数选项】 ‘
# 定义变量 empty_row_count
awk开始运行一遍
BEGIN{
}
# 如果是空行,则 empty_row_count+1 每个记录运行一遍
【匹配】{
}
# 打印变量 empty_row_count
最后运行输出
END{
}’ files
一)、选项参数说明:
主要是的:
1. -F fs or --field-separator fs
指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:
awk 默认每行是以‘ [ \t]+’分割的(就是输入域分隔符FS,连续多个空格为一个分割), 行分隔符是以'\n'回车(RS)
文本如下:
第1,2,3行是2个空格分割, 第4行是tab分割
更改分隔符eg1: awk '{print NF}' t2 用默认进行分割 第一行分割为2个域 最后一行也是2个行,
修改下用空格做分割:awk -F "[ ]" '{print NF}' t2 第一行变成了3个域 最后一行没有分割
如何用两个符号一起分割比如两个空格来分割,一个空格不算分割
awk -F "[ ][ ]" '{print NF}' t2
awk -F " |" '{print NF}' t2 都可以表示 只用两个空格来表示分隔符【】表示里面的符号选一个, |表示或
如何表示用两个符号都可以作为分隔符比如我用a或者b分割
awk -F "[ab]" '{print NF}' t2
awk -F "a|b" '{print NF}' t2
2. -v var=value or --asign var=value
赋值一个用户定义变量
这里注意
-v 引用$var 一定加引号。。。
我不懂shell 别笑话
以下也可以使变量带入 但是从{}执行体才可以带入,BEGIN{}没有带入, var="$var" 一定跟在awk 之后 文件之前
网上说如下方法都可行:
一:"'$var'"
这种写法大家无需改变用'括起awk程序的习惯,是老外常用的写法.如:
var="test"
awk 'BEGIN{print "'$var'"}'
这种写法其实际是双括号变为单括号的常量,传递给了awk.
如果var中含空格,为了shell不把空格作为分格符,便应该如下使用:
var="this is a test"
awk 'BEGIN{print "'"$var"'"}'
二:'"$var"'
这种写法与上一种类似.如果变量含空格,则变为'""$var""'较为可靠.
三.把括起awk程序的''变为"",使用"$var"
如:
$var="this is a test"
awk 'BEGIN{print "$var"}"
这是因为在""里$是特殊字符,而在''里$是普通字符.
四:export 变量,使用ENVIRON["var"]形式,
如:
$var="this is a test";export $var
awk 'BEGIN{print ENVIRON["var"]}'
3.
-f scripfile or --file scriptfile
从脚本文件中读取awk命令
上一章节已经说了
注释:
注释有两种方式,
一个是# ,一个是/*xxxxxx*/
二)、基础结构
分为BEGIN模块 {}中间模块 END结束模块
三)、内部运算符
运算符
|
描述
|
= += -= *= /= %= ^= **=
|
赋值
|
?:
|
C条件表达式
|
||
|
逻辑或
|
&&
|
逻辑与
|
~ ~!
|
匹配正则表达式和不匹配正则表达式
|
< <= > >= != ==
|
关系运算符
|
空格
|
连接
|
+ -
|
加,减
|
* / %
|
乘,除与求余
|
+ - !
|
一元加,减和逻辑非
|
^ ***
|
求幂
|
++ --
|
增加或减少,作为前缀或后缀
|
$
|
字段引用
|
in
|
数组成员
|
假如我要判定aaa在整个文件中,这里注意数组是以字典形式存储,什么都可以,不像C++, 查询时候也是查询是否在字典中,而不是字典对应的值
四)、内部函数
1、算术函数查询
函数名
|
说明
|
atan2( y, x )
|
返回 y/x 的反正切。
|
cos( x )
|
返回 x 的余弦;x 是弧度。
|
sin( x )
|
返回 x 的正弦;x 是弧度。
|
exp( x )
|
返回 x 幂函数。
|
log( x )
|
返回 x 的自然对数。
|
sqrt( x )
|
返回 x 平方根。
|
int( x )
|
返回 x 的截断至整数的值。
|
rand( )
|
返回任意数字 n,其中 0 <= n < 1。
|
srand( [Expr] )
|
将 rand 函数的种子值设置为 Expr 参数的值,或如果省略 Expr 参数则使用某天的时间。返回先前的种子值。
|
这里说一下,rand()和srand(),只需要在BEGIN里面加上srand(),以后rand()都是随机的,我以为rand()比较浪费时间,其实不浪费,测试了一下,跟调用其他命令相差相比时间基本没有
cat t3|awk 'BEGIN{sum=0;srand()}{rand();sum++}END{print sum}'
2、字符串函数查询:
函数
|
说明
|
gsub( Ere, Repl, [ In ] )
|
除了正则表达式所有具体值被替代这点,它和 sub 函数完全一样地执行,。
|
sub( Ere, Repl, [ In ] )
|
用 Repl 参数指定的字符串替换 In 参数指定的字符串中的由 Ere 参数指定的扩展正则表达式的第一个具体值。sub 函数返回替换的数量。出现在 Repl 参数指定的字符串中的 &(和符号)由 In 参数指定的与 Ere 参数的指定的扩展正则表达式匹配的字符串替换。如果未指定 In 参数,缺省值是整个记录($0 记录变量)。
|
index( String1, String2 )
|
在由 String1 参数指定的字符串(其中有出现 String2 指定的参数)中,返回位置,从 1 开始编号。如果 String2 参数不在 String1 参数中出现,则返回 0(零)。
|
length [(String)]
|
返回 String 参数指定的字符串的长度(字符形式)。如果未给出 String 参数,则返回整个记录的长度($0 记录变量)。
|
blength [(String)]
|
返回 String 参数指定的字符串的长度(以字节为单位)。如果未给出 String 参数,则返回整个记录的长度($0 记录变量)。
|
substr( String, M, [ N ] )
|
返回具有 N 参数指定的字符数量子串。子串从 String 参数指定的字符串取得,其字符以 M 参数指定的位置开始。M 参数指定为将 String 参数中的第一个字符作为编号 1。如果未指定 N 参数,则子串的长度将是 M 参数指定的位置到 String 参数的末尾 的长度。
|
match( String, Ere )
|
在 String 参数指定的字符串(Ere 参数指定的扩展正则表达式出现在其中)中返回位置(字符形式),从 1 开始编号,或如果 Ere 参数不出现,则返回 0(零)。RSTART 特殊变量设置为返回值。RLENGTH 特殊变量设置为匹配的字符串的长度,或如果未找到任何匹配,则设置为 -1(负一)。
|
split( String, A, [Ere] )
|
将 String 参数指定的参数分割为数组元素 A[1], A[2], . . ., A[n],并返回 n 变量的值。此分隔可以通过 Ere 参数指定的扩展正则表达式进行,或用当前字段分隔符(FS 特殊变量)来进行(如果没有给出 Ere 参数)。除非上下文指明特定的元素还应具有一个数字值,否则 A 数组中的元素用字符串值来创建。
|
tolower( String )
|
返回 String 参数指定的字符串,字符串中每个大写字符将更改为小写。大写和小写的映射由当前语言环境的 LC_CTYPE 范畴定义。
|
toupper( String )
|
返回 String 参数指定的字符串,字符串中每个小写字符将更改为大写。大写和小写的映射由当前语言环境的 LC_CTYPE 范畴定义。
|
sprintf(Format, Expr, Expr, . . . )
|
Ere都可以是正则表达式
3、格式化字符串输出查询(sprintf使用)
格式化字符串格式:
其中格式化字符串包括两部分内容: 一部分是正常字符, 这些字符将按原样输出; 另一部分是格式化规定字符, 以"%"开始, 后跟一个或几个规定字符,用来确定输出内容格式。
格式符
|
说明
|
%d
|
十进制有符号整数
|
%u
|
十进制无符号整数
|
%f
|
浮点数
|
%s
|
字符串
|
%c
|
单个字符
|
%p
|
指针的值
|
%e
|
指数形式的浮点数
|
%x
|
%X 无符号以十六进制表示的整数
|
%o
|
无符号以八进制表示的整数
|
%g
|
自动选择合适的表示法
|
awk 'BEGIN{n1=124.113;n2=-1.224;n3=1.2345; printf("%.2f,%.2u,%.2g,%X,%o\n",n1,n2,n3,n1,n1);}'
124.11,18446744073709551615,1.2,7C,174
4、一般函数查询:
函数
|
说明
|
close( Expression )
|
用同一个带字符串值的 Expression 参数来关闭由 print 或 printf 语句打开的或调用 getline 函数打开的文件或管道。如果文件或管道成功关闭,则返回 0;其它情况下返回非零值。如果打算写一个文件,并稍后在同一个程序中读取文件,则 close 语句是必需的。
|
system(Command )
| |
Expression | getline [ Variable ]
|
从来自 Expression 参数指定的命令的输出中通过管道传送的流中读取一个输入记录,并将该记录的值指定给 Variable 参数指定的变量。如果当前未打开将 Expression 参数的值作为其命令名称的流,则创建流。创建的流等同于调用
popen
子例程,此时 Command 参数取 Expression 参数的值且 Mode 参数设置为一个是 r 的值。只要流保留打开且 Expression 参数求得同一个字符串,则对 getline 函数的每次后续调用读取另一个记录。如果未指定 Variable 参数,则 $0 记录变量和 NF 特殊变量设置为从流读取的记录。
|
getline [ Variable ] < Expression
|
从 Expression 参数指定的文件读取输入的下一个记录,并将 Variable 参数指定的变量设置为该记录的值。只要流保留打开且 Expression 参数对同一个字符串求值,则对 getline 函数的每次后续调用读取另一个记录。如果未指定 Variable 参数,则 $0 记录变量和 NF 特殊变量设置为从流读取的记录。
|
getline [ Variable ]
|
将 Variable 参数指定的变量设置为从当前输入文件读取的下一个输入记录。如果未指定 Variable 参数,则 $0 记录变量设置为该记录的值,还将设置 NF、NR 和 FNR 特殊变量。
|
5、
时间函数
函数名
|
说明
|
mktime( YYYY MM DD HH MM SS[ DST])
|
生成时间格式
|
strftime([format [, timestamp]])
|
格式化时间输出,将时间戳转为时间字符串
具体格式,见下表.
|
systime()
|
得到时间戳,返回从1970年1月1日开始到当前时间(不计闰年)的整秒数
|
6、
strftime日期和时间格式说明符
格式
|
描述
|
%a
|
星期几的缩写(Sun)
|
%A
|
星期几的完整写法(Sunday)
|
%b
|
月名的缩写(Oct)
|
%B
|
月名的完整写法(October)
|
%c
|
本地日期和时间
|
%d
|
十进制日期
|
%D
|
日期 08/20/99
|
%e
|
日期,如果只有一位会补上一个空格
|
%H
|
用十进制表示24小时格式的小时
|
%I
|
用十进制表示12小时格式的小时
|
%j
|
从1月1日起一年中的第几天
|
%m
|
十进制表示的月份
|
%M
|
十进制表示的分钟
|
%p
|
12小时表示法(AM/PM)
|
%S
|
十进制表示的秒
|
%U
|
十进制表示的一年中的第几个星期(星期天作为一个星期的开始)
|
%w
|
十进制表示的星期几(星期天是0)
|
%W
|
十进制表示的一年中的第几个星期(星期一作为一个星期的开始)
|
%x
|
重新设置本地日期(08/20/99)
|
%X
|
重新设置本地时间(12:00:00)
|
%y
|
两位数字表示的年(99)
|
%Y
|
当前月份
|
%Z
|
时区(PDT)
|
%%
|
百分号(%)
|
7、 切分字符串
格式:
split (string, array, field separator)
split (string, array) -->如果第三个参数没有提供,awk就默认使用当前FS值
。
第一个是要被分割的字符串,第二个是数组,把分割后的东西放到数组里面,标号1,2,3....,最后的分隔符,前后用“”或者//符号表示,
8、替换字符串
sub匹配第一次出现的符合模式的字符串,相当于 sed 's//' 。
gsub匹配所有的符合模式的字符串,相当于 sed 's//g'
这个函数返回的值是替换掉的几个地方,不是替换完的字符串,所以不可以$4=gsub("xxx","",$4)
格式:gsub(r,s,t) r要被替换的字符串或者正则表达式,s要替换成的字符串表达式,t表示要替换的目标或者地方
假如我把文件中的“: ”替换成冒:,
9、截取字符串
格式:
substr(s,p) 返回字符串s中从p开始的后缀部分
substr(s,p,n) 返回字符串s中从p开始长度为n的后缀部分
从第一个开始不是第0个,后面的是截取几个字符
10、长度计算
格式:
length(string)
11、索引计算
格式:
index($0,string)
从$0或者其他目标字符串中找到string出现的位置,从1开始计算,没找到返回0,后面string只能是string,不能使正则表达式
12、调用系统命令
1.getline
格式:
形式
|
设置
|
getline
|
$0,NF,NR,FNR
|
getline var
|
var,NR,FNR
|
getline<file
|
$0,$1…$NF,NF
|
getline var<file
|
var
|
cmd|getline
|
$0,NF,
$1…$NF
|
cmd|getline var
|
var
|
如果是getline,则就从处理的文本拿行,改变行号,$0
如果是getline var,则不改变$0,依旧改变行号,变量var存储得到的行
如果是getline <“files”,则不从处理文本中获取行,所以NR啥的不变,只改变$0,
如果是cmd|getline;则不从处理文本获取信息,所以NR不变,但是$0用于存储信息
NR必须是从处理的文本获取信息才会变化,只有存入变量的时候,$0才不会变化,否则变化
awk getline接收用户输入,有两种形式:
getline string < "/dev/tty"
getline string < "-" 标准输入
NR和$0都改变了
NR没有变化,$0变化了
2.system调用系统命令
system(string)
3.close 关闭句柄
13、三种语句
1.顺序语句
用逗号分开就可以不多说
2.循环语句for
格式1:
for(变量 in 数组)
{语句}
格式2:
for(变量;条件;表达式)
{语句}
第一种是数组遍历的方式,第二种是固定循环
3.循环语句while
格式:
do
{语句}while(条件)
4.判断语句
if(表达式)
{语句1}
else if(表达式)
{语句2}
else
{语句3}
因为awk基本机构如下 awk ‘/匹配/{action}’
匹配如果没有 默认为真,就是1
{action} 默认是print $0
基本与C 语言一样
break
|
当 break 语句用于 while 或 for 语句时,导致退出程序循环。
|
continue
|
当 continue 语句用于 while 或 for 语句时,使程序循环移动到下一个迭代。
|
next
|
能能够导致读入下一个输入行,并返回到脚本的顶部。这可以避免对当前输入行执行其他的操作过程。
|
exit
|
语句使主输入循环退出并将控制转移到END,如果END存在的话。如果没有定义END规则,或在END中应用exit语句,则终止脚本的执行。
|
五)、内部变量
重要的都标红了
变量
|
描述
|
$n
|
当前记录的第n个字段,字段间由FS分隔。
|
$0
|
完整的输入记录。
|
ARGC
|
命令行参数的数目。
|
ARGIND
|
命令行中当前文件的位置(从0开始算)。
|
ARGV
|
包含命令行参数的数组。
|
CONVFMT
|
数字转换格式(默认值为%.6g)
|
ENVIRON
|
环境变量关联数组。
|
ERRNO
|
最后一个系统错误的描述。
|
FIELDWIDTHS
|
字段宽度列表(用空格键分隔)。
|
FILENAME
|
当前文件名。
|
FNR
|
同NR,但相对于当前文件。
|
FS
|
字段分隔符(默认是任何空格)。
|
IGNORECASE
|
如果为真,则进行忽略大小写的匹配。
|
NF
|
当前记录中的字段数。
|
NR
|
当前记录数。
|
OFMT
|
数字的输出格式(默认值是%.6g)。
|
OFS
|
输出字段分隔符(默认值是一个空格)。
|
ORS
|
输出记录分隔符(默认值是一个换行符)。
|
RLENGTH
|
由match函数所匹配的字符串的长度。
|
RS
|
记录分隔符(默认是一个换行符)。
|
RSTART
|
由match函数所匹配的字符串的第一个位置,从1开始计数。
|
SUBSEP
|
数组下标分隔符(默认值是\034)。
|
六)、自定义函数
1. awk中的函数定义位置更灵活(shell中必须在调用之前定义),可以在任意地方定义,用{}括起即可,关键字是function或func;
2. 可以定义参数,但调用时可带可不带(后面会详述);
3. 函数可以直接使用awk中的变量,包括域变量($1、$2...)和函数外定义的其它变量,这些变量可以看做是全局变量,如果是直接使用,则函数中对变量的修改将影响该变量的值;
echo "123456" | awk '
{
var = 10;
MyFunc();
print $1;
print var;
}
function MyFunc()
{
print $1;
var += 20;
$1 = "abcdefg";
}'
输出:
123456
abcdefg
30
4. 如果想要使得函数对变量的修改不改变原变量的值,那么需要通过参数传递的方式来实现;
echo "123456" | awk '
{
var = 10;
MyFunc(var);
print var;
}
function MyFunc(var)
{
var += 20;
}'
输出:
10
5. 函数中定义的变量默认也是全局的,如果想要使其作为局部变量,可以使用在参数中定义,但调用时不传入该参数的方式(shell函数中可以使用local关键字来定义局部变量);
echo "123456" | awk '
{
MyFunc();
print var1;
print var2;
}
function MyFunc(var1)
{
var1 = 0;
var2 = 20;
}'
输出:
(空)
20
6. 函数返回值使用 ret = FuncName(arg1, arg2, arg3, ...);
7. 函数的参数如果是标量则是传值,数组则是传引用,函数中改变数组的值可以改变全局数组中的值。
echo "123456" | awk '
{
a = 10;
b[1] = 15;
MyFunc(a, b);
print a;
print b[1];
}
function MyFunc(x, y)
{
x = 0;
y[1] = 20;
}'
输出
10
20
七)、数组
1、定义方法
1:可以用数值作数组索引(下标)
Tarray[1]=“cheng mo”
Tarray[2]=“800927”
2:可以用字符串作数组索引(下标)
Tarray[“first”]=“cheng ”
Tarray[“last”]=”mo”
Tarray[“birth”]=”800927”
echo "1 2 "|awk '{
array[$1]++;
array[1]++;
array["1"]++
}END{
for(k in array)
print k,array[k]
}'
1 3
也就是说$1,1,"1"造成的字典是一样的
2、数组相关函数
- length:得到数组长度(length方法使用)
- asort:对数组进行排序,只是对值排序,下角标变成数字1234,返回数组长度
echo "5 a cb dd" | awk ‘
{
for(i=1;i<=NF;i++)
array[$i]=$i
}END{
print "长度:"length(array)
for(i in array)
{
print i,array[i]
}
print "长度:"length(array),asort(array)
for(i in array)
{
print i,array[i]
}
}’
长度:4
cb cb
dd dd
a a
5 5
长度:4 4
1 5
2 a
3 cb
4 dd
3、数组遍历、是否存在
- 有序遍历
awk
'BEGIN{info="it is a test";tlen=split(info,tA," ");for(k=1;k<=tlen;k++){print k,tA[k];}}'
1
it
2
is
3
a
4
test
- 无序遍历
awk 'BEGIN{info="it is a test";split(info,tA," ");for(k in tA){print k,tA[k];}}'
4 test
1 it
2 is
3 a
- 判断键值存在以及删除键值:
直接是if(k in array)
awk ‘BEGIN{tB[“a”]=”a1″;tB[“b”]=”b1″;if( “c” in tB){print “ok”;};for(k in tB){print k,tB[k];}}’
a a1
b b1
- 删除数组
删除数组中某个内容 用delete array["xxxx"]
删除整个数组 delete array
如何建立一个空数组 a[1]=2;delete a
awk 'function min(a,b){
if(a>b) return b
else return a
}
{
for(i=1;i<=NF;i++)
array[$i]=$i
}END{
print "最原始数组长度:"length(array)
for(i in array)
{
print i,array[i]
}
print "排序数组长度:"length(array),asort(array)
for(i in array)
{
print i,array[i]
}
delete array[1]
print "删除一个数组长度:"length(array)
for(i in array)
{
print i,array[i]
}
delete array
print "删除整个数组长度:"length(array)
for(i in array)
{
print i,array[i]
}
}'
echo "a b" |sh -x awk.sh
最原始数组长度:2
a a
b b
排序数组长度:2 2
1 a
2 b
删除一个数组长度:1
2 b
删除整个数组长度:0
4多维数组
多为数组用array[a,b,c]
a.b,c用数字或者字符串都可以,其实是一维数组,中间用SUBSEP连接而已
如果想要把a,b,c分别取出来,先split(多维数组内容k,拆分到的数组k2,SUBSEP);然后遍历拆分到的数组k2
八)、定向输出、输入
重新打开命令用>
追加方式打开用>>
awk '{if($1%2==0) print $0 >^Cs";else print $0 >"os"}' t3
三、正则表达式
总结一下:
+表示至少一个 ;?表示0或者1个;* 表示0或者多个
|表示或者
(aaa)组合表示连着
{3} 有三个前面的字符,{3,5}3到5个
[a-h],[1-9]表示1个a到h或者1到9中的字符
^ 表示开头 $表示结尾
~匹配上
.一个字符
\转义
字符
|
功能
|
+
|
指定如果一个或多个字符或扩展正则表达式的具体值(在 +(加号)前)在这个字符串中,则字符串匹配。命令行:
awk '/smith+ern/' testfile
将包含字符
smit
,后跟一个或多个
h
字符,并以字符
ern
结束的字符串的任何记录打印至标准输出。此示例中的输出是:
smithern, harry smithhern, anne
|
?
|
指定如果零个或一个字符或扩展正则表达式的具体值(在 ?(问号)之前)在字符串中,则字符串匹配。命令行:
awk '/smith?/' testfile
将包含字符
smit
,后跟零个或一个
h
字符的实例的所有记录打印至标准输出。此示例中的输出是:
smith, alan smithern, harry smithhern, anne smitters, alexis
|
|
|
指定如果以 |(垂直线)隔开的字符串的任何一个在字符串中,则字符串匹配。命令行:
awk '/allen | alan /' testfile
将包含字符串
allen
或
alan
的所有记录打印至标准输出。此示例中的输出是:
smiley, allen smith, alan
|
( )
|
在正则表达式中将字符串组合在一起。命令行:
awk '/a(ll)?(nn)?e/' testfile
将具有字符串
ae
或
alle
或
anne
或
allnne
的所有记录打印至标准输出。此示例中的输出是:
smiley, allen smithhern, anne
|
{m}
|
指定如果正好有 m 个模式的具体值位于字符串中,则字符串匹配。命令行:
awk '/l{2}/' testfile
打印至标准输出
smiley, allen
|
{m,}
|
指定如果至少 m 个模式的具体值在字符串中,则字符串匹配。命令行:
awk '/t{2,}/' testfile
打印至标准输出:
smitters, alexis
|
{m, n}
|
指定如果 m 和 n 之间(包含的 m 和 n)个模式的具体值在字符串中(其中m<= n),则字符串匹配。命令行:
awk '/er{1, 2}/' testfile
打印至标准输出:
smithern, harry smithern, anne smitters, alexis
|
[String]
|
指定正则表达式与方括号内 String 变量指定的任何字符匹配。命令行:
awk '/sm[a-h]/' testfile
将具有
sm
后跟以字母顺序从
a
到
h
排列的任何字符的所有记录打印至标准输出。此示例的输出是:
smawley, andy
|
[^ String]
|
在 [ ](方括号)和在指定字符串开头的 ^ (插入记号) 指明正则表达式与方括号内的任何字符不匹配。这样,命令行:
awk '/sm[^a-h]/' testfile
打印至标准输出:
smiley, allen smith, alan smithern, harry smithhern, anne smitters, alexis
|
~,!~
|
表示指定变量与正则表达式匹配(代字号)或不匹配(代字号、感叹号)的条件语句。命令行:
awk '$1 ~ /n/' testfile
将第一个字段包含字符
n
的所有记录打印至标准输出。此示例中的输出是:
smithern, harry smithhern, anne
|
^
|
指定字段或记录的开头。命令行:
awk '$2 ~ /^h/' testfile
将把字符
h
作为第二个字段的第一个字符的所有记录打印至标准输出。此示例中的输出是:
smithern, harry
|
$
|
指定字段或记录的末尾。命令行:
awk '$2 ~ /y$/' testfile
将把字符
y
作为第二个字段的最后一个字符的所有记录打印至标准输出。此示例中的输出是:
smawley, andy smithern, harry
|
. (句号)
|
表示除了在空白末尾的终端换行字符以外的任何一个字符。命令行:
awk '/a..e/' testfile
将具有以两个字符隔开的字符
a
和 e 的所有记录打印至标准输出。此示例中的输出是:
smawley, andy smiley, allen smithhern, anne
|
*(星号)
|
表示零个或更多的任意字符。命令行:
awk '/a.*e/' testfile
将具有以零个或更多字符隔开的字符
a
和 e 的所有记录打印至标准输出。此示例中的输出是:
smawley, andy smiley, allen smithhern, anne smitters, alexis
|
\ (反斜杠)
|
转义字符。当位于在扩展正则表达式中具有特殊含义的任何字符之前时,转义字符除去该字符的任何特殊含义。例如,命令行:
/a\/\//
将与模式 a // 匹配,因为反斜杠否定斜杠作为正则表达式定界符的通常含义。要将反斜杠本身指定为字符,则使用双反斜杠。有关反斜杠及其使用的更多信息,请参阅以下关于转义序列的内容。
|
范围模板
别人给的概念:范围模板匹配从第一个模板的第一次出现到第二个模板的第一次出现之间所有行。如果有一个模板没出现,则匹配到开头或末尾。如$ awk '/root/,/mysql/' test将显示root第一次出现到mysql第一次出现之间的所有行。
稍微纠正一下上面的话
1、只有第一个模板匹配到,才会找第二个匹配的地方
seq 20 |awk '/22/,/34/'
这个是匹配不到任何行的
2、如果两个模板多次匹配到,则把其中之间的行都匹配出来
zgl@zgl-TM1701 ~/learn_work/awk $ seq 20 |awk '/6/,/8/'
6
7
8
16
17
18
3、如果第一个模板多次出现,第二个比第一个少,则把第一个一直遇到第二个模板才结束,否则到结尾
zgl@zgl-TM1701 ~/learn_work/awk $ seq 20 |awk '/6/,/12/'
6
7
8
9
10
11
12
16 //这里重新开始第一个模板,直到结束没遇到第二个
17
18
19
20
zgl@zgl-TM1701 ~/learn_work/awk $ cat t2
aaa
bbb
ccc
aaa
ccc
aaa
bbb
ccc
zgl@zgl-TM1701 ~/learn_work/awk $ cat t2 |awk '/aaa/,/bbb/'
aaa
bbb
aaa
ccc
aaa
bbb
4、中间不能用; 用;表示两个或者,就是匹配到其中一个就行
zgl@zgl-TM1701 ~/learn_work/awk $ seq 30 |awk '/6/;/12/'
6
12
16
26
四、特别注意
- cat t2|sh -x awk.sh 假设awk.sh 里面有3个awk语句或者其他接收流的语句,就是先给第一个,如果第一个awk只有BEGIN,那就给第二个awk,直到所有行执行玩或者sh执行完
- 怎么输出或者cmd中带“{”,我不会,求指教
微信添加,请自我备注,一起探讨