sed 、awk用法
Sed 命令:
sed是一种流编辑器,它是文本处理中非常中的工具,能够完美的配合正则表达式使用,功能不同凡响。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。
主要用法:
-格式1: 前置命令|sed [选项] ‘编辑指令’
-格式2:sed [选项] ‘编辑指令’ 文件名称
常见命令选项:
-n :屏蔽默认输出(全部文本)
-i :直接修改文件内容
-e :可指定多个处理动作
-r :启用扩展的正则表达式,若与其他选项一起使用,应作为首个选项
{} :可组合多个命令,以分号分隔
基本的处理动作:
操作符 用途 指令示例
p 打印行 2,4p 输出2、3、4行 2p;4p 输出2、4行
d 删除行 2,4d 删除2-4行
s 字符串替换 s/old/new/ 将每行中第一个old替换为new
操作实例:
输出文本:
sed -n ‘p’ a.txt 输出所有行
sed -n ‘4p’ a.txt 输出第4行
sed -n ‘4,7p’ a.txt 输出第4-7行
sed -n ‘4,+10p’ a.txt 输出第4行及其后的10行内容
sed -n ‘/^bin/p’ a.txt 输出以bin开头的行
sed -n ‘p;n’ a.txt 输出奇数行
sed -n ‘n;p’ a.txt 输出偶数行
sed -n ’10,${n;p}’ a.txt 输出第10行至文件末尾的所有的奇数行
替换文本:
sed ‘s/xml/XML/’ a.txt 将每行中的第1个xml替换为XML
sed ‘s/xml/XML/3’ a.txt 将每行中的第3个xml替换为XML
sed ‘s/xml/XML/g’ a.txt 将每行中的所有的xml替换为XML
sed ‘s/xml//g’ a.txt 将文件中所有的xml删掉
sed ‘s/doc/&s/g’ a.txt 将文件中doc都替换为docs
sed ‘4,7s/^/#/’ a.txt 将第4-7行注释掉
sed ‘s/^#an/an/’ a.txt 解除以#an开头行的注释
删除文本:
sed ‘3,5d’ a.txt 删除3-5行
sed ‘/xml/d’ a.txt 删除所有包含xml的行
sed ‘/xml/!d’ a.txt 删除不包含xml的行
sed ‘/^install/d’ a.txt 删除以install开头的行
sed ‘$d’ a.txt 删除最后一行
sed ‘/^$/d’ a.txt 删除空行
sed ‘/^$/{n;/^$/d}’ a.txt 删除重复空行
应用实例:
去除URL中的文件目录:
echo "http://www.a.com/dddddda/1/2/3/a.mp4?aeafafa=23&afafa=23" |sed '{s/?.*//;s/http:\/\///}' | grep -o "/.*"
Awk命令:
Awk是一种程序性语言,它具有一般语言具有的功能。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。
命令格式:
-格式1:前置命令|awk [选项] ‘[条件]{编辑指令}’
-格式2:awk [选项] ‘[条件]{编辑指令}’ 文件名
Awk环境变量:
变量 |
描述 |
$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函数所匹配的字符串的第一个位置。 |
SUBSEP |
数组下标分隔符(默认值是\034)。 |
运算符:
运算符 |
描述 |
= += -= *= /= %= |
赋值 |
?: |
C条件表达式 |
|| |
逻辑或 |
&& |
逻辑与 |
~ ~! |
匹配正则表达式和不匹配正则表达式 |
< <= > >= != == |
关系运算符 |
空格 |
连接 |
+ - |
加,减 |
* / & |
乘,除与求余 |
+ - ! |
一元加,减和逻辑非 |
^ *** |
求幂 |
++ -- |
增加或减少,作为前缀或后缀 |
$ |
字段引用 |
应用实例:
条件语句:
awk中的条件语句是从C语言中借鉴来的
ls -l |awk 'BEGIN {size=0;print "[start]size is ", size} {if($5!=4096){size=size+$5;}} END{print "[end]size is ", size/1024/1024,"M"}'
循环语句:
awk中的循环语句同样借鉴于C语言,支持while、do/while、for、break、continue,这些关键字的语义和C语言中的语义完全相同
awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd
Awk使用方法:
awk '{pattern + action}' {filenames}
其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号({})不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。 pattern就是要表示的正则表达式,用斜杠括起来。
cat /etc/passwd |awk -F ':' '{print $1}'
awk工作流程是这样的:读入有'\n'换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域。默认域分隔符是"空白键"
cat /etc/passwd |awk -F ':' 'BEGIN {print "name,shell"} {print $1","$7} END {print "blue,/bin/nosh"}'
awk工作流程是这样的:先执行BEGIN,然后读取文件,读入有/n换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域,随后开始执行模式所对应的动作action。接着开始读入第二条记录······直到所有的记录都读完,最后执行END操作。
ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size}'
统计目录下文件字节大小
zcat access.log.gz |awk 'BEGIN {size=0;} {size=size+$10;} END{print "log size is ", size/1024/1024/1024*8/300 "Gbps"}'
可以用于统计日志中的带宽
匹配日志中区域运营商:
zcat access.log.gz|nali3 |awk '$2 ~/.*浙江.*电信/ {print $0}'
awk应用实例:
- $ awk '/^(no|so)/' test-----打印所有以模式no或so开头的行。
- $ awk '/^[ns]/{print $1}' test-----如果记录以n或s开头,就打印这个记录。
- $ awk '$1 ~/[0-9][0-9]$/(print $1}' test-----如果第一个域以两个数字结束就打印这个记录。
- $ awk '$1 == 100 || $2 < 50' test-----如果第一个或等于100或者第二个域小于50,则打印该行。
- $ awk '$1 != 10' test-----如果第一个域不等于10就打印该行。
- $ awk '/test/{print $1 + 10}' test-----如果记录包含正则表达式test,则第一个域加10并打印出来。
- $ awk '{print ($1 > 5 ? "ok "$1: "error"$1)}' test-----如果第一个域大于5则打印问号后面的表达式值,否则打印冒号后面的表达式值。
$ awk '/^root/,/^mysql/' test----打印以正则表达式root开头的记录到以正则表达式mysql开头的记录范围内的所有记录。如果找到一个新的正则表达式root开头的记录,则继续打印直到下一个以正则表达式mysql开头的记录为止,或到文件末尾。