sed,awk

sed

  • sed的强项是替换字符,可是也能够筛选,不过没有颜色高亮显示
  • 如图,sed '/root/'p test.txt
  • 若是要筛选字符,必须写在 '//' 中间,是特定格式
  • 因此想搜索关键字 root 就要写做 '/root/'
  • 旁边的 p 表示print打印,若是不写,就不会显示任何信息
  • 写了 p 筛选内容才会显示在屏幕上
  • 后面test.txt是想搜索的文件名称
  • 可是这样有一个问题,如图,执行命令后出现不少不须要的信息
  • 这是由于筛选完成后,这条命令还会把文件内的全文都打印到筛选信息下面
  • 如图,第一行和第二行如出一辙
  • 第一行就是命令筛选出来的信息,第二行开始就是原文件全文的内容
  • 因此若是不想执行命令后,把原文件内容也打印出来,须要使用参数 n
  • 如图,使用 -n 参数,下面就只会显示筛选出来的信息,不会有原文的内容

  • 如图,还可使用正则符号 + 来筛选
  • 可是须要使用 r 参数,或者脱义+号如 +
  • 参数 r 功能相似 grep 的参数 -E
  • 使用了r参数就能够直接识别一些须要脱义的字符

  • 还能够直接选择显示某一行
  • 如图,sed -n '2'p test.txt 就能够直接显示原文件第二行内容
  • 写数字能够不用加 //
  • 如图,这样能够显示 第二行 到 第五行 的内容
  • 如图,这样能够显示第25行到最后一行的内容
  • 符号 $ 表明剩下的全部内容
  • 25,$ 就表示从 25行开始,而后到最后一行
  • 如图 1,$ 这样就能够把全部内容都打印出来
  • 1,$ 表示从第一行开始,到最后一行
  • 也就是所有的内容

  • 参数 -e 能够写一段操做
  • 若是想在一条命令里面执行多段操做,可使用 -e
  • 如图,sed -e '1'p -e '/root/'p -n test.txt
  • 每一段操做都须要写一次 -e
  • 每一个 -e 后面能够写一段操做
  • 命令会先执行第一段操做,而后再执行第二段操做
  • 图中的筛选结果,第一行结果是第一段命令的结果
  • 下面两行结果是第二段命令的结果

  • 也能够不区分大小写来匹配字符
  • 如图,匹配条件是 '/bus/'Ip
  • p 是打印结果的意思,I 就是不区分大小写的参数
  • 这里加上 I 参数,就能够不区分 bus 的大小写来匹配

  • 如图,这条命令意思是,删除 1-25 行的内容,显示剩下的内容
  • 参数 d 就是删除的意思,条件 1,25 就表示1-25行
  • 下面显示的结果就是删除了1-25行后剩下的内容
  • 可是实际上,这个命令不会对原文件进行修改
  • 也就是说,实际上原文件并无被删除任何内容
  • 若是一个文件很大,打开须要很长的时间
  • 就可使用这个命令,将不须要看的部分删除,只看剩下的部分
  • 这样就能够节约时间,又不会对原文件形成修改

  • 除了不修改原文件删除内容显示外,还能够对原文件进行修改
  • 如图,使用了 -i 参数
  • 加入 -i 参数就能够实际上对原文件进行修改
  • 也就是说把原文件的1-25行删除
  • 下面 wc -l 查看文件总行数,只剩下5行,原本有30行的

  • 还能够针对特定关键词进行删除
  • 如图,'/user2/'d 这里 user2 就是关键词
  • 这条命令能够把包含关键词 user2 的数据行删除掉
  • cat 查看文件,能够看到 包含user2的行不见了

  • 上图是查找替换的命令
  • 意思是把1-10行内,全部root都替换为toor
  • 首先,1-10s 就表示1-10行的意思,s 参数就表明替换功能
  • 也就是1-10行内进行替换,表示替换的范围
  • /root/toor/ 意思就是 root 被替换为 toor
  • g 是全局替换的意思
  • 假设一行里面有两个 root,若是不加 g 参数,就只会替换第一个root
  • 只有使用了全局替换参数 g 才会把每一行的每一个 root 都进行替换
  • 否则的话就只会替换每一行遇到的第一个 root

  • 替换也可使用正则表达式
  • 上图,1,10s 表示在1-10行内替换
  • /ro+/r/ 意思是把符合正则 ro+ 的字符串都替换为 r
  • g 就是全局替换,后面使用管道符而后用head显示前10行
  • 能够看到,第一行原本是 root 的地方变成了 rt
  • 这里 sed -r 还须要用-r参数
  • 由于使用了正则表达式 + 号
  • 若是不加-r参数会不识别 + 号

  • 上图是一个复杂的正则使用案例
  • head test.txt |sed -r 's/([^:]+):(.*):([^:]+)/\3:\2:\1/'
  • 这条命令是,先用 head 获得 text.txt 的前十行内容,而后传给后面的 sed 处理
  • 后面的 sed 对传过来的内容进行处理,把第一列的内容与最后一列的内容进行调换
  • 首先 sed -r 由于正则使用了 + 因此要 -r 才能识别
  • 而后是 s ,表示替换的意思,前面没有行数限制范围,就表示替换范围为所有内容
  • 而后是 ([^:]+):(.*):([^:]+) 这表示被替换的内容格式
  • 结构是3个部分,三个() 中间是两个 : 进行间隔,这就是被替换的内容格式
  • [^:] 表示任意非 : 的字符,[^:]+ 表示1个或者多个连续非 : 字符组合
  • ([^:]+) 小括号括起来表示这是一个总体
  • ([^:]+):表示第一个 : 加上左边的非 : 字符
  • (.*): 表示任意多个字符一直匹配到最后一个 : 为止
  • 而后最右边是 ([^:]+) 也就是说最后一个 : 右边的非 : 字符
  • 之因此每一个部分都要用 () 括起来,是由于可使用 \1 , \2 , \3 表明它们
  • 而后后面的被替换格式就是 \3:\2:\1
  • 意思就是把原来的 第一个() 与 第三个() 位置进行调换
  • 这样 第一列 与 最后一列 就被调换了位置

  • 这个例子里面,被替换的是 /sbin/nologin
  • 替换上面字符串的是 123
  • 原来的分隔符是 /
  • 可是由于被替换字符串里面含有 / ,这样会跟原来的分隔符 / 发生冲突
  • 系统会报错,因此如今把原来的分隔符 / 换成了 @
  • 这样就不会报错了
  • 也可使用 脱义字符 \ 对 /sbin/nologin 进行转换
  • 如 /sbin/nologin 可是这样很难看,因此推荐使用 @ 代替 / 作分隔符

  • 这个是把原文全部大小写字母删除的例子
  • 首先,s 表示替换范围是全文
  • [a-zA-Z] 表示被替换的字符是符合这个条件的字符
  • 任意一个字符只要是大写字母,或者小写字母都符合这个被替换条件
  • 而后后面是 // ,中间没有写任何东西,就是 空字符
  • 意思就是把任意 大小写字母 替换成 空字符
  • 也就是把全文的字母都删除了,下面能够看到字母所有不见了

  • 这个案例是,在每一行的前面加上 aaa:
  • 首先是 sed -r 不少特殊符号不使用 r 参数都会不识别
  • 因此通常用到特殊符号的时候,前面都加上 -r 参数保证不出错误
  • 而后是 s 表示替换范围是 全文
  • 而后是 (.*) 表示整行全部字符,小括号()表示这是一个总体
  • 也就是说,被替换的对象是整行全部字符
  • 而后 aaa:& ,这里 & 就表示前面的小括号的内容
  • 也可使用 \1 表示前面的小括号
  • 当只有一个小括号的时候,可使用 & 表明前面的 小括号总体
  • 因此 aaa:& 就表示把 aaa: 放在了 (.*) 每行全部字符的前面
  • 这样整条命令的意思就是,把原来的 每一行内容
  • 替换为 aaa: + 原来的每一行内容
  • 也就是在原来每行内容的前面,加上了 aaa:

awk

  • awk 能够支持分段筛选,就是能够把一行字符分红不一样的段
  • awk -F ':' '{print $1}' test.txt
  • 这条命令的意思是,把test.txt的每行数据用 : 来进行分隔
  • 而后打印出第一段的数据
  • 这里 -F 就是指定分隔符的选项, 而后后面接 ':' 就是把 : 指定为每段的分隔符
  • 后面 '{print $1}' 就是打印第一段的意思, $1 就表示第一段
  • 若是使用 $0 ,就表示打印全部段,也就是说所有信息,$0表示全部段

  • 如图,不使用 -F 参数,直接 print $0
  • 这样就会把原文所有打印出来
  • 不过若是不设置 -F 分隔符的话,默认的分隔符就是 空格 或者 空白字符

  • 若是想同时打印 多段 字符
  • 如图,使用 print $1,$3,$4 ,使用逗号分隔,写上不一样段的标号
  • 这样就能够打印出 第一段,第三段,第四段的信息

  • 还能够在打印不一样段信息的时候,设置不一样段信息之间的分隔符
  • 如图,使用双引号加井号 "#" 这样就设置了 # 做为不一样段的分隔符
  • 看下面打印出来的信息,不一样段之间是用 # 分隔的,原来是空格

  • 如图,使用 '/oo/' 就能够筛选包含关键字 oo 的数据行

  • 这条命令意思是,分隔符为 : ,筛选出 第一段 含有关键字 oo 的数据行
  • 这里设置了 : 做为分隔符来分段
  • $1 表示 第一段数据,符号 ~ 表示 匹配
  • 后面是 '/oo/' 就表示匹配 oo 关键字
  • 这样就把每一行数据都用 : 进行了分段,而后就能够找出每一行数据的第一段数据里面
  • 含有 oo 关键字的那一行数据

  • 也能够匹配正则表达式,如图,匹配 oo+
  • 第一段数据含有关键字 o+(1-n)o 的数据行

  • awk -F ':' '/root/ {print $1,$3} /user/ {print $1,$3,$4}' test.txt
  • 这条命令是执行了两段指令
  • 第一段指令是 /root/ {print $1,$3}
  • 首先匹配包含 root 关键字的数据行,而后打印出 第一段 和 第三段
  • 第二段指令是 /user/ {print $1,$3,$4}
  • 首先匹配包含 /user/ 关键字的数据行,而后打印出 第一段,第三段,第四段
  • 这就是在一条命令里面同时执行多段匹配
  • 下面使用 grep 匹配 root或者user 能够看到
  • 上面匹配的数据行都是包含 root 或者 user 的数据行

  • 这里,/root|user/ 意思就是匹配包含关键字 root 或 user 的数据行
  • 而后 print $0 就是打印整行

  • 如图,还能够进行 数值 的匹配
  • 第一条命令,$3==0 是指
  • 用 : 分隔每行数据,而后找出每行数据 第三段 等于 0 的数据行
  • 第二条命令增长了 {print $1} 就是只打印 第一段 数据的意思
  • 第三条命令就是匹配 第三段 大于等于 1000 的数据行
  • 而后只打印 第一段 数据
  • 第四条命令跟第三条同样,可是是打印整行数据
  • 还能够对字符串进行布尔运算
  • 如图,$7!="/sbin/nologin" 意思就是匹配 第七段 不等于 "/sbin/nologin" 的数据行
  • 符号 != 表示 不等号,由于 /sbin/nologin 是字符串,全部要用双引号括起来

  • 还能够把两段数据进行比较匹配
  • 如图,第一条命令的条件是 '$3<$4'
  • 意思就是匹配 第三段 小于 第四段 的数据行
  • 下面的结果,第三段的数值都比第四段小
  • 第二条命令匹配条件是 $3==$4
  • 意思就是匹配 第三段 等于 第四段 的数据行
  • 下面结果能够看到,第三段数值都等于第四段数值

  • 还能够同时使用多个条件匹配
  • 如图, $3>"5" && $3<"7" 就表示匹配
  • 第三段数据包含 同时大于5小于7 的关键字 的数据行

  • 也可使用或者的条件匹配
  • 如图,匹配条件是 $3>1000 || $7=="/sbin/nologin"
  • 意思是 第三段 大于 1000 或者 第七段 等于 /sbin/nologin
  • 符合以上条件的数据行会被匹配出来

  • 如图,匹配条件是 $3>1000 || $7 ~ /bash/
  • 这个条件的意思是,第三段 大于 1000
  • 或者 第七段 包含关键字 bash
  • 符合以上条件的数据行会被匹配出来
  • $7 ~ /bash/ 意思就是在 第七段 里面匹配 bash
  • 符合 ~ 表示匹配, // 中间的字符串就是要匹配的字符串

  • 可使用awk内置变量设置匹配后的数据分隔符
  • 如图,{OFS="#"} 这里 OFS 就是设置分隔符的变量
  • 赋值 # 给 OFS,这样匹配以后的数据就会以 # 分隔
  • 这里的语法是,先写 变量,而后写匹配条件,最后是 print 语句

  • 还能够把条件语句跟print语句写在一块儿
  • 使用嵌套的花括号写
  • {if ($3>1000) {print $1,$2,$3,$4}} 就是 $3 大于 1000 的数据行
  • 打印 第 1,2,3,4 段数据
  • 这就是把条件语句跟print语句用花括号括起来变成一体

  • 还有两个awk内置变量,NR,NF
  • NR 表示 行号, NF 表示 段数
  • 如图,条件是 {print NR":"$0}
  • 意思是 打印 NR(行号)+ 字符(:)+ 整行数据($0)
  • 下面的数据能够看到,每行数据的开头处,都多了 1:,3:等 行号+: 的数据

  • 还能够显示每一行的段数
  • 如图, print NF":"$0
  • 就是 打印 每一行总共几段(NF)+ : + 整行数据
  • 下面数据能够看到,每行数据前面多了 数字+: ,数字就是 每行的段数

  • NR,NF 还能够作判断使用
  • 如图,第一条命令 NR<=10 就是把前十行打印出来
  • 由于 NR<=10 就是行号在1-10之内的数据行会被匹配出来,也就是前十行
  • 第二条命令 NR<=10 && $1 ~ /root|sync/
  • 这是多项筛选,首先是 NR<=10 前10数据会被匹配出来
  • 而后是 $1 ~ /root|sync/ 第一段数据匹配关键字 root 或者 sync 的数据行
  • 符合 ~ 表明匹配,root|sync 就是 root 或 sync 的意思
  • 符合以上条件的数据行会被匹配出来
  • 第三条命令 NF==6 && $1 ~ /root|sync/
  • 首先匹配 NF==6 也就是段数为 6 的数据行
  • 而后匹配 第一段包含关键字 root或sync 的数据行

  • 这个例子是在 NR 和 NF 前面都加上 $ 符号
  • 好比第一行打印的数据是 $1:$6
  • 由于第一行 NR 是 1 ,$NR 就是 $1 也就是第一行的第一段
  • 而后是 : + $6 ,由于第一行总共有6段
  • 因此 $NF 就是 $6 ,也就是第一行的第六段
  • 最后打印的数据就是 第一段 + : + 第六段
  • 而后后面的数据以此类推,第二行就是 第二段 + : + 第七段
  • 由于第二行总共有7段,第二行的行号是2

  • 除了判断,还能够赋值
  • 如图,首先 head test.txt的前三行数据而后传给后面的 awk命令
  • 而后在awk命令里面 $1="root" 进行赋值
  • 而后看下面结果,前三行的第一段信息所有变成了 root
  • 这里还使用了 OFS=":" 的参数
  • 由于使用赋值操做后,-F 不起做用,因此须要使用 OFS 参数才能设置分隔符

  • 这个例子是 求一列全部值的和
  • 首先 tot=tot+$3 是一个循环
  • tot是新建的一个变量,初始值默认为0
  • 这个式子会循环每一行的第三段,也就是第三列数据,一直到最后一行为止
  • 好比第一行的时候,tot=0
  • 因此 tot+$3 = 0 + 第一行第三段的值($3)
  • 而后第二次循环,由于 tot = 0+第一行第三段的值($3) = 第一行第三段的值($3)
  • 因此第二次循环就是 tot = 第一行第三段的值($3) + 第二行第三段的值($3)
  • 以此类推,直到最后一行,这样就把全部行的第三段的值都相加了
  • 最后的结果就是 第三列的和
相关文章
相关标签/搜索