linux 三剑客sed,awk及作业

  • 文本处理:

       vim,vi
       sed,awk,grep
       cut,cat,tr,uniq,sort,comm
 

一、sed

(1)原理
         非交互式的编辑器
          流式
         执行流程:read ==> excute ==>print(打印) ==>repeat
(2)语法:
         格式一:sed    选项  '[定址符]命令' 文件
         格式二:前置命令 | sed  选项 '[定址符]命令' 文件
(3)打印
          -n:不打印模式空间   

  例:           sed -n '/^root/,/^apache/ p' /etc/passwd 从一行到另一行之间所有的行
                 sed -n 'm,/^apache/ p' /etc/passwd   从m行到apache开头的行的所有
                 sed -n 'm,n p' /etc/passwd    从第m行到n行的所有行
                 sed -n '/^root/,n p' /etc/passwd 从root开头的行以及往下数n行
                 sed -n '$ p' /etc/passwd   显示最后一行
                 sed -n 'm~a p' /etc/passwd(a:步长) 从m行开始每隔a行显示


(4)多点编辑问题 ---(查找passwd中以root和apache开头的行)
         ① -e: ( \ ,{} )断行
              例:\:    

            sed -n \
             > -e '/^root/p' \
             > -e '/^apache/p' \
             > /etc/passwd

       结果:
              root:x:0:0:root:/root:/bin/bash
              apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

                     {}:

           sed -n '{
            > /^root/ p
            > /^apache/ p 
            > }' /etc/passwd

                       
         ② - f:文本       

  例: [root@localhost test2]# cat com.txt
                             /^root/p
                             /^apache/ p 

         [root@localhost test2]# sed -n -f com.txt /etc/passwd

           
(5)删除
        d

 例:   sed '/^root/ d' /etc/passwd       删除root开头的行
        sed '2,3 d' /etc/passwd           删除2-3行
        sed '/^root/,3 d'/etc/passwd      删除从root开始的的3行
        sed '3, /^apache// d' /etc/passwd 删除第3行到apache开头的行
         
        sed '/^root/,+3 d'/etc/passwd     删除算root开始向后在加的3行
        sed '/^$/ d'/etc/passwd           删除空行
        sed '/^#/d'/etc/passwd            删除以#开头的行

                  
(6)读写

            sed '1 r b.txt' a.txt                    在a.txt文件的第一行下面插入b.txt
             sed '1 w c.txt' a.txt               将c.xt中的第一行另存为a.txt
             sed  '/^102/,/^103/ r b.txt' test1   在test1中以102到103开头的行下都插入b.txt
             sed  '/^102/,3 r b.txt' test1        在test1中以102到1第三行下都插入b.txt
             sed  '1,3 r b.txt' test1           在test1中第一行到第三行下都插入b.txt

 
(7)替换
           sed '/^x/s/旧/新' 文件名

 

       例:

  •       sed '2 s/old/new/'/etc/passwd  把2行第一个old改为new
  •       sed '2,5 s/old/new/'/etc/passwd  把2-5行第一个old改为new
  •       sed '2,5 s/old/new/g'/etc/passwd 把2-5行所有old改为new
  •       sed '2,5 s/old/new/i'/etc/passwd 把2-5行第一个old改为new不区分大小写
  •       sed '2,5 s/old/new/w d.txt'/etc/passwd 把2-5行第一个old改为new 并写入到d.txt文件里

                      先在b.txt中写上想要查的文件的路径 /etc/passwd /etc/shadow

  •        sed 's/^/ls -l /e'/etc/passwd  相当于 ls -l /etc/passwd;ls-l /etc/shadow  
  •        sed 's/^.*/<&>/g' passwd 把文件passwd中每一行都用<>框起来
  •        sed 's/^[0-9][0-9][0-9]/[&]/g' passwd 把文件中三位数字开头的数字用[]框起来             

               
(8)后项引用

 

  •   sed 's/\([^,]*\).*/\1/g' test  显示匹配每一行 开头逗号结尾第一个部分

101
102
103
104
105

  •  sed 's/\([^:]*\).*/\1/' /etc/passwd (分组) 截取以:为一个分段中的第一段
  •  echo "This Is a Test" |sed 's/\(\b[A-Z]\)/\(\1\)/g'   

       把This Is a Test写入到文件中并匹配单词开始或结束为A-Z的用()括起来

       (T)his (I)s a (T)est

  •  cat numbers.txt 
  • 1
    12
    123
    1234
    12345
    123456
  •  sed 's/\(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)/\1\2,\3/g' numbers.txt 
  •         分为3个组,第一组为开头或以0-9数字开头一次;第二组为0-9的数字一次或多次;第三组为0-9的数字三次

          从后往前分析,先匹配第三组三位数,与一二组用逗号隔开​​​​​​

1
12
123
1,234
12,345
123,456

  •  sed 's/^\([^,]*\),\([^,]*\),\([^,]*\)/\1,\3/' test     分为三组,显示第一组和第三组用逗号连接 

101,CEO  
102,IT Manager  
103,Sysadmin  
104,Developer  
105,Sales Manager 

 

(9)文本块

 c   替换当前
[root@localhost test2]# sed '/^GATEWAY/ c GATEWAY=192.168.42.2' ifcfg-eth0
i   行前插入
[root@localhost test2]# sed '/^GATEWAY/ i  DNS2=8.8.4.4' ifcfg-eth0 
a  行后插入文本
[root@localhost test2]# sed '/^GATEWAY/ a  DNS1=8.8.8,8' ifcfg-eth0 
[root@localhost test2]# sed '1 a  DNS1=8.8.8,8' ifcfg-eth0    在第一行后插入
[root@localhost test2]# sed '$ a  DNS1=8.8.8,8' ifcfg-eth0    在最后一行插入

(10)sed 中的正则

  • 用户提权:

(1)su
   普通用户的su进制,PAM机制(P433)
   gpasswd -a username wheel :all root
(2)sudo 
   三个分组:用户   命令   主机

   cd /etc/sudoers.d  写入一个文件 test   关于用户提权

前三行为用户test1有权利修改ip,使用别名实现,且不需要输入密码

第四行为test1拥有权限使用/usr/sbin下的所有命令,但没有删除用户的权限

第五行为test1拥有查看/var/log/message*下的所有文件,并且避免查看其他文件

(3)LADP 统一身份认证
   扩展堡垒机(jumpserver)
 

二、awk

  • 语法
  1. awk [参数] 'BEGIN{}//{print $1} END{}' file
  2. comm |awk [参数] ‘BEGIN{} // {print $1} END{}'

 

-F 

指明输入时用到的字段分隔符

-v  var=value

自定义变量

① -F

  •  awk -F: '/root/' passwd      显示出含有root的行
  • awk -F: '{print $1}' passwd     显示出以:为分隔符的第一部分
  •  awk -F: '/root/{print $1,$3}' passwd  显示出含root以:为分隔符的第一,三部分
  •   awk 'BEGIN{FS=":"} /^root/{print $1,$3}' passwd
  •  awk -F',' '{print $2$3}' 3.txt 显示出以逗号为分隔符的二三部分
  • awk -F',' '{print $2':'$3}' 3.txt   显示出以逗号为分隔符的二三部分之间用冒号分隔
  •  awk -F ',' 'BEGIN{OFS=":"}{print $2,$3}' 3.txt
     

 

  •  df -P |grep '/'|awk '$4 > 25000{print $4}'

字符串常量

\反斜线
\aaltert字符,通常为ASCII BEL字符
\b退格键
\f换页
\n换行符
\r回车
\t水平制表符
\v垂直制表符
\c字符由十六进制数字下面的\x中的字符串来表示
\xhex digits字面字符c
  • awk -F: 'BEGIN{print "username \n-------------\n"} /root/ {print $1} END {print "-----------"}' passwd   

显示含有root的行的以冒号为分隔符的第一部分在这前一行插入username换行符-----换行符,末尾插入-------

  • awk -F: '{print $1"\t"$3}' passwd

显示passwd中第一部分和第三部分中间的空格水平制表符显示

格式化输出

%c

显示字符的ASCII
%d, %i显示十进制整数
%e, %E显示科学计数法数值
%f显示为浮点数
%g, %G以科学计数法或浮点形式显示数值
%s显示字符串
%u无符号整数
%%显示%自身

-

左对齐(默认右对齐) %-15s
+显示数值的正负符号 %+d

printf:

格式化输出,默认不会自动换行

 

  •  awk -F: '{printf "%s",$1}' passwd   格式输出文件中第一部分的字符串,输出为一行
  •  awk -F: '{printf "%-20s %10d\n",$1,$3}' passwd  文件中第一部分以字符串形式左对齐,第三部分以十进制右对齐格式化输出
  • awk -F: '{printf "username: %s,UID:%d\n",$1,$3}' passwd   格式输出文件中第一部分的字符串且前面加上username:,第三部分的十进制数且前面加上UID: ,每一行都换行

变量

1.内置变量

②-v 开始执行程序之前都是变量值

FS:输入字段分隔符,默认为空白字符

  •  awk -v FS=':' '{print $1,FS,$3}' passwd  显示一三部分,中间用空格分隔

OFS:输出字段分隔符,默认为空白字符

  • awk -v FS=':' -v OFS=':' '{print $1,$3,$5}' passwd


RS:输入记录分隔符,指定输入时的换行符,原换行符仍有效

  •  awk -v ORS='**' '{print}' this.txt

NF:字段数量

  •  awk -F: '{print NF}' /etc/fstab   显示文件以 冒号为分隔符的字段数
     

NR:行号

  •  awk '{print NR}' /etc/fstab  打印出行号
     

FNR:各文件分别计数,行号

  •  awk '{print FNR}' /etc/fstab /etc/inittab  打印出这两个文件的行号
     

FILENAME:当前文件名

  •  awk '{print FILENAME}' /etc/fstab   打印出行数对应的文件名
  •  awk 'NR==1 {print FILENAME}' /etc/fstab  打印出第一行对应的文件名

ARGC:命令行参数的个数

  • awk '{print ARGC}' /etc/fstab

ARGV:数组,保存的是命令行所给定的各参数

  • awk 'BEGIN {print ARGV[1]}' /etc/fstab

2.自定义变量

(1)-v var=value

(2)在program中直接定义

 awk -v test='hello gawk' '{print test}' /etc/fstab   指定test的值,并输出文件对应的行

 awk -F: '{sex="male";print $1,sex,age;age=18}' /etc/passwd  指定sex和age的值,并输出第一部分,和指定的值 


3.其他

(1)sort
按数字排序
[root@www test]# sort -n file1
逆序排列
[root@www test]# sort -r file1
安月分排列
[root@www test]# sort -M file1
需要合并两个排过序的文件,而且不需要对合并后的文件再次排序
[root@www test]# sort -m sorted1 sorted2
测试文件是否被排过序
[root@www test]# sort -nC file2
指定主建来排序
[root@www test]# sort -k 4 file1

(2)uniq
uniq命令通过消除重复内容,从而给输入中找出单一的行,也可以找出重复行。uniq只能用于拍过序的数据输入,因此,uniq要么使用管道,要么将排序的文件作为输入。

[root@www test]# cat file11
112
112
134
344
123
134

  • 只显示连续唯一的行

[root@www test]# uniq file11

  • 不显示连续唯一行

[root@www test]# uniq -u file11

  • 显示不重复的唯一行

[root@www test]# sort file11 |uniq -u

  • 显示唯一行

[root@www test]# sort file11 |uniq 

  • 统计各行在文中出现的次数

[root@www test]# sort file11 |uniq -c
     

  • 找出文中的重复行

[root@www test]# sort file11 |uniq -d
 

  • 找出文中的重复行并编号

[root@www test]# sort file11 |uniq -d -c

-s 指定可以跳过前n个字符。 -w 指定用于比较的最大字符数

  • 对文件排序,跳过前两个字符去重,留下其中最大字符的

 [root@www test]#sort file10 |uniq -s 2 -w 2

(3)comm

交集:打印两个文本所共有的行。
求差:打印指定文件所包含的且不相同的那些行。
差集:打印出包含在文件A 中,但不包含在其他指定文件中的那些行。

[root@www files]# cat file1
applex
orange
gold
silver
steel
iron
[root@www files]# cat file2
orange
gold
cookies
carrot
[root@www files]# sort file1 -o file1;sort file2 -o file2
[root@www files]# comm file1 file2
apple
             carrot
             cookies
                               gold
iron
                               orange
silver  
steel

输出的第一列为只有在file1中出现的行,第二列为只有在file2中出现的行,第三列为file1和file2中共有的行。

[root@www files]# comm file1 file2 -1 -2
gold
orange
[root@www files]# comm file1 file2 -1
carrot
cookies
    gold
    orange
[root@www files]# comm file1 file2 -1 -3
carrot
cookies

-1 从输出中删除第1列
-2 从输出中删除第2列
-3 从输出中删除第3列

 

4、作业

1.1.假设我们有这样一个待处理的文件"grade.txt"

M.Tansley   05/99   48311    Green   8   40   44
J.Lulu     06/99   48317     green   9   24   26
P.Bunny     02/99   48      Yellow   12   35   28
J.Troll    07/99   4842     Brown   -3    12   26 26
L.Tansley  05/99   4712       Brown   -2  12   30 28

#打印整个文件

  •  awk '{print }' grade.txt

#打印第一和第四个域

  • awk '{print$1,$4 }' grade.txt

#打印表头

  • awk 'BEGIN{print "Name          ab       cd    color     1   2   3\n------------------------------------------------"} {print} ' grade.txt

#下面代码打印第四部分包含 Brown 的行

  • awk '$4~/Brown/ {print $0}' grade.txt

#非精确匹配 -- 匹配第三部分含有48的行

  •  awk '$3~/48/ {print}' grade.txt

#精确匹配--匹配第三部分是48的行

  • awk '$3=="48" {print}' grade.txt

#不匹配 使用 ‘!~’----第四部分不包含 Brown 的行

  • awk '$4 !~/Brown/ {print}' grade.txt

#小于-- 打印出$6<$7的行后加上Try better at the next comp

  • awk '$6< $7 {print $0 "$1 Try better at the next comp"}' grade.txt  

#设置大小写

  •  awk '/[Gg]reen/' grade.txt

#匹配第一个域的第四个字符是‘a’

  • awk '$1~ /^...a/' grade.txt

#''匹配,使用 ‘|’ ,需使用括号括起来 ---匹配含有Yellow或Brown的行

  • # awk '/(Yellow|Brown)/' grade.txt 

 

2.sedawk有什么区别?

(1)awk:按列()操作;sed:按行操作

(2)awk:文本处理语言,适合对文本进行抽取处理;sed:非交互式的编辑器,适合对文本进行编辑

3.awk要处理域的时候,以哪个参数作为分割参数?   答:  -F

4.请打印出/etc/passwd 第一个域,并且在第一个域所有的内容前面加上用户帐号:

  •  awk -F:  '{print "用户账号:" $1}' passwd

5.请打印出/etc/passwd 第三个域和第四个域

  • awk -F: '{print $3,$4}' passwd

6.匹配/etc/passwd 第三域大于100的显示出完整信息

  •  awk -F: '$3>100{print $0}' passwd

7.请打印第一域,并且打印头部信息为:这个是系统用户,打印尾部信息为:"================"

  • awk -F: 'BEGIN{print "这个是系统用户 \n"} {print $1} END{print"========="}' passwd

8.打印行号小于15的,并且最后一域匹配sbin的信息.

  •  awk -F: '{if ($NR<15 && $NF~/sbin/) print$0}' passwd

9.请打印出第一域匹配daemon的信息.

  • cat passwd |zwk -F: '$1=="daemon"' passwd

10.请打印出第三域数字之和

  •  awk -F: '{sum=sum+$3}END{print sum}' passwd

11.请将/etc/passwd 中的root替换成gongda,记住是临时替换输出屏幕看到效果即可.

  • awk -F: 'gsub(/root/,"gongda"){print }' passwd

12.请匹配passwd最后一段域bash结尾的信息,有多少条

  • awk -F: '($NF~/bash/){print NR}' /etc/passwd |wc -l

13.请同时匹配passwd文件中,带mailbash的关键字的信息

  •  awk -F: '{if($0~/mail/ || $0~/bash/) print $0}' passwd

14.请匹配passwd第三域总大于500的相关信息.

  •  awk -F: '{if($3>50) print $0}' passwd


 

15.编写文件fifile的内容如下:

Mike Harrington:[510] 548-1278:250:100:175

Christian Dobbins:[408] 538-2358:155:90:201

Susan Dalsass:[206] 654-6279:250:60:50

Archie McNichol:[206] 548-1348:250:100:175

Jody Savage:[206] 548-1278:15:188:150

Guy Quigley:[916] 343-6410:250:100:175                

Dan Savage:[406] 298-7744:450:300:275

Nancy McNeil:[206] 548-1278:250:80:75

John Goldenrod:[916] 348-4278:250:100:175

Chet Main:[510] 548-5258:50:95:135

Tom Savage:[408] 926-3456:250:168:200

Elizabeth Stachelin:[916] 440-1763:175:75:300     

Mike 名

Harrington 姓

[510] 548-1278 电话

250:100:175 过去三个月里的捐款

(1))显示所有电话号码

  •  awk -F: '{print $2}' file

(2)显示Dan的电话号码        # awk -F: '{if($1~/Dan/) print $2}' file

(3)显示Susan的名字和电话号码   # awk -F: '{if($1~/Susan/) print $1,$2}' file

(4)显示所有以D开头的姓         # awk -F '[: ]+' '{if($2~/^D/) print $2}' file

(5))显示所有以一个C或E开头的名   # awk -F '[: ]+' '{if($1~/^[C|E]/) print $1}' file
  

(6)显示所有只有四个字符的名,这里可以使用length函数,举例: length($1)==10 $1字符为10

# awk -F: '{print $1}' file|awk '{if(length($1)==4) print $1}'

(7)显示所有区号为916的人名  # awk  '{print $2}' file |awk -F: '{if($2~/916/) print$1}'

(8)显示Mike的捐款.显示每个值时都有以$开头.如$250$100$175    # awk -F: '{if($1~/Mike/) print "$"$3"$"$4"$"$5}' file

(9)显示姓,其后跟一个逗号和名   # awk -F '[: ]+' '{print $2","$1}' file

16 、统计/etc/fstab 文件中每个文件系统类型出现的次数

17、统计/etc/fstab 文件中每个单词出现的次数

 awk '{for(i=0;i<=NF;i++){count[$i]++}}END{for(i in count){print i,count[i]}}' fstab
 

18 、提取出字符串Yd$C@M05MB%9&Bdh7dq+YVixp3vpw中的所有数字

echo "Yd$C@M05MB%9&Bdh7dq+YVixp3vpw"|awk -F "[^[:digit:]]" '{for(k=1;k<=NF;k++) {count[$k]}}END{for(i in count){printf "%s",i}printf "\n"}'

20:统计netstat -tan 中各状态的次数

21:统计出/etc/passwd文件中shell的种类和个数

22:计算/etc/passwd中所有用户的UID平均数,以及GID平均数.

23:使用:符号做分隔符,将字段逆序输出/etc/passwd文件的每行

24:统计psVSZ,RSS各自总和

25:根据uid值给用户分等级 Admin system users输出格式:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值