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的主要内容,如果未能解决你的问题,请参考以下文章