L-1-23 awk&sed

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了L-1-23 awk&sed相关的知识,希望对你有一定的参考价值。

[awk]

awk <option> '<PATTERN> {<action>}' <filename> [<filename2> ...]    //文本处理工具

比如:df -Ph |awk '{print $1,$3}'

//awk中大括号中应该用双引号


awk会去分割每行并成分为字段,如:

this is a  cat.

$1   $2 $3 $4

$4就是cat.  

$0代表这一整行


******************<option>******************

-F<interpunction>  //指定分隔符,可以用双引号括起来

比如:awk -F: {print $1,$3} /etc/passwd         //passwd文件中字段是由:分开的而不是由空格分开的。多个分割符连在一起时只算一个。(cut是算多个)


-v <var>="<string>"       //awk可以设置内置变量,-v用来设置内置变量

也可以这样表达awk 'BEGIN{a="Hello"};{print a}'   //这里多语句用;分开



*****************内置变量*******************   //内置变量在大括号中直接写,双引号内的是字符串

FS     输入分割符,默认是空格


OFS    输出分割符,写print命今时,$<num>之间用,分开的,默认是空格,但改后就有变化

如:awk -F: '{OFS="#"}{print $1,$2}' /etc/passwd


RS     输入换行符,默认是回车


ORS    输出换行符,默认是回车


FNR    当前处理文件的行数,单文件时处理到第几行就是第几行。


NR     所有文件处理的行数,用于多文件时使用

如:awk 'END{print NR}' /etc/passwd /etc/fstab  //显示passwd和fstab一共几行


NF     当前处理行的分割成的字段数。$NF是当前行的最后一个字段




*****************<PATTERN>****************  //类似于sed的address,决定需要操作的行

/<RegExp>/  //正则表达式,要用斜杠括起来,只对符合条件的行进行操作

如:awk -F: '/r..t/{print $1}' /etc/passwd    //以包含/r..t/表达式的行作为目标,将它们打印出来


<expression> //表达式,只对符合条件的行进行操作

如:awk -F: '$3 >= 500{print $1,$3}' /etc/passwd     //在passwd文件中$3代表UID,这里比较UID是否大于500,并打印出大于500的用户名和UID

如:awk -F: '$7~bash${print $1,$7}' /etc/passwd      //在passwd文件中$7是用户的shell,这里判断$7是否以bash结尾,并打印出符合条件的用户名与用的shell


<range>   //指定范围,与sed的指定范围不太一样。


{BEGIN|END} //表示命今只在开始或结束前施行一次。有了这个PATTERN,awk命令后面可以不跟文件

如:awk 'BEGIN{print "one\ntwo\nthree"}'     //\n是换行符


<null>  //什么都不写表示读取所有行



********************表达式*********************

计算操作 用法如:awk 'BEGIN{print 1+1}'

有以下几种:

-<num>       取负值


+<figure>    将非数字改成数字,boolean中是为1,否为0

如:awk 'BEGIN{a=+(6 > 7);print a}' 结果是0

awk 'BEGIN{a=+(7 > 6);print a}',结果是1


还有一些计算符与shell一致:+-*/^(次方)%(取余)


赋值操作符,用法如:awk 'BEGIN{i++;print i}'

这些与shell一致:= += -= *= /= ^= %= ++ --


布尔值,结果是True或False

如:< > == <= >= 

!=(不等)

<string> ~ <pattern> //<string>是否满足<pattern>,满足为True

<string> !~ <pattern> //<string>是否满足<pattern>,不满足为True


逻辑关系符

和shell一样:&& ||


条件表达式

<selector>?<if-true>:<if-false>  //三目结构,判断<selector>,结果为真值为<if-ture>,否则为<if-false>

如:awk 'BEGIN{a=3;b=4;max=a>b?a:b;print max}'


********************数组*************************

例子:awk -F: '{shell[$NF]++}END{for(A in shell){print A,shell[A]}}' /etc/passwd

这个数组里第一个读出的数组是shell[/bin/bash]这是中括号里的下标可以是任何字符串,++代表shell[/bin/shell]的值变成1

第二行得到shell[/sbin/nologin]++,最后的循环时可以打印出下标A,这里是下标/bin/bash,而shell[A]是/bin/bash用户个数


******************<action>************************

print <item>  打印指定字段

如:awk -F: '{print $1}' /etc/passwd

awk -F: '{print NF}' /etc/passwd    //参数NF不用打括号

awk 'BEGIN{print "Hello"}'


printf <format>,<item1>

%c         ASCII码形式显示

%d,%i      十进制整数

%e,%E      科学计数法

%f         浮点数形式显示

%g,%G      科学计数法浮点数形式显示

%s         字符串形式表示

%u         无符号整数

%%         %自身

修饰符

<num>      以<num>个数字来表示

-          左对齐 //不写默认为右对齐

用法:awk -F: '{printf "%-15s %i\n",$1,$3}' /etc/passwd

%-15s是$1的格式,%i是$3,\n是换行


if <condition> <then> else <else_than>

如:awk -F: '{if ($1=="root") print $1;else print "not root"}' /etc/passwd


while <condition> {<command>;[<command> ..]}

如:awk -F: '{i=1;while(i<=3){print$i;i++}}' /etc/passwd


do-while {<command>} while <condition>

如:awk -F: '{i=q;do{print$i;i++}while(i<=3)}' /etc/passwd


for

如:awk -F: '{for(i=1;i<=3;i++)print$i}' /etc/passwd


case switch(<condition>) {case {<var>|<regexp>}:<command> [...] default:<command> }


break,continue 用法类似bash


next跳过当前行,直接进行下一行

如:awk -F: '{if($3%2==0)next;print $1;$3}' /etc/passwd 

-------------------------------------------------------------------------------------------------------------------------------------------

[sed]

sed '<AdressCommand>' <file>       流编辑器

-n 静默模式,不在模式空间的内容。(只显示修改的内容)

比如 sed '1p' /etc/passwd 结果是输出第一行后再打输出passwd文件

sed -n '1p' /etc/passwd 结果是只输出第一行

-i 直接修改原文件

-e '<SCRIPT>' [-e <script>] ... :同时执行多个sed脚本

-f <file> :通过读取一个文件来读取里面的sed脚本

-r 使用扩展正则表达式。

Address:  //Address是选择须要修改的行,Command是设置做什么

1. StartLine,EndLine

   eg: 1,100

   //$表示最后一行,$-n表示最后第n行。

   比如:sed '1,100d' <filename>  //删除<filename>的1-100行。

   sed '1,$-3d' <filename>  //比如一共5行,最后的第三行正好是第三行,所以是删除前1-3行。

2. /RegExp/

   eg: /^root/

  //正则表达式来代表符合条件的行

  比如:sed '/^root/d' <filename>  //删除文件中以root开头的行

  sed '/oot/d' /etc/passwd   //删除文件中带有oot字符的行

3. /pattern1/,/pattern2/

  //第一次被pattern1匹配到的行,至第一次被pattern2匹配到的行结束,中间的所有行进行操作。

  比如:sed -n '/^root/,/^nobody/p' /etc/passwd //输出root开头的行到nobody开头的行

4.LineNumber

  //指精确的行

  比如:sed '1d' <filename>  //删除第一行

5.StartLine,+N

  //从startLine开始,向后的N行。共N+1行。

  比如:sed -n '1,+3p' /etc/passwd //输出passwd文件的第一行与接下来的三行。

  sed '/^root/,+3a \hello' /etc/passwd //在passwd文件以root开头的行,与此行接下来的3行下都追加hello

Command:

 d:删除符合条件的行。

 p:显示符合条件的行。

 a \<string>:在指定的行后面追加新行,内容为“<string>”(\n 换行符)

 比如:sed '/^root/,+3a \hello' /etc/passwd //在passwd文件以root开头的行,与此行接下来的3行下都追加hello

 sed '1,3a first line\nsecond line' /etc/passwd  //在文件1-3行下各添加两行first line second line

 i \<string>:在指定的行前面追加新行,内容为“<string>”,与a类似。

 r <file>: 将指定的文件内容添加至符合条件的行处

 比如:sed '1r /etc/fstab' /etc/passwd //把fstab内容添加到passwd第一行下

 w <file>: 将指定范围内的内容另存为至指定文件。

 s/<pattern>/<string>/<※> 查找每一行符合条件的<pattern>(能用正则表达式),并将每行中第一次匹配到的串替换成<string>。写了s就不用写address了,默认修改每一行。

   ※:g:全局替换。  //即替换所有,而不是每行第一个

       i:忽略大小写

 eg:sed 's/oot/OOT/'/etc/fstab

 eg:sed -r '[email protected]^[[:space:]]+#@@g' /etc/inittab  //s不一定是s///,也可以是[email protected]@@、s###等其他特殊字符

 string这里可以使用&,代表了引用匹配的条目。

 比如:正则表达式l..e,可能是like或是love,要它们匹配后都加r,那么该写成's/l..k/&r/',&代表了匹配的文字,它可以在任何地方,r&,1&1

 sed 's#l\(..e\)#L\1#g' <filename>  //只改括号内的部分,用了括号第二部分就可以引用。


比如说adress是2,command是p,那么2p就是第二行的意思,sed -n '2p' <filename> 就是读取文件的第二行。 

如果需要修改的字符是特殊字符,那么就需要\符转译:sed '/^\//d' /etc/fstab  删除/开头的行,其中\是特殊字符。


以上是关于L-1-23 awk&sed的主要内容,如果未能解决你的问题,请参考以下文章

sed && awk

Sed&awk笔记之awk

sed & awk 概述

AWK&SED

sed && awk lookup 解答

sed && awk工具 及一些常用的shell脚本