shell 中的文本处理 grep sed awk

shell 中的文本处理

1  grep  文本过滤命令

Global search regular expression and print out the line
全面搜索研究正则表达式并显示出来
grep 命令是一种强大的文本搜索工具,根据用户指定的"模式"对目标文本进行匹配检查,打印匹配到的行
由正则表达式或者字符及基本文本字符所编写的过滤条件

 1.1>gerp命令的使用:
grep ^root passwd #root 开头的行
grep root$ passwd #root 结尾的行
grep -i root passwd #不区分大小写
grep -v root passwd #反向过滤
grep -E "root|ROOT" passwd #过滤含有root或者ROOT的行
grep -E "^root|ROOT" passwd #过滤以root开头或者含有ROOT 的行
1.2>实验现象操作:
1 cp /etc/passwd /mnt    /
2 cd /mnt/
3 ls
4 grep root passwd
5 grep ^root passwd
6 grep root$ passwd
7 vim passwd
8 grep root$ passwd
9 grep  -i root passwd
10grep  -v root passwd
11grep -E "root|ROOT" passwd
12grep -v -E "root|ROOT" passwd
13grep -v -E "^root|ROOT" passwd

过滤出passwd文件中root在中间的行
1>grep -i root passwd | grep -v -i "^root|root$"
2>grep -v -i -E "^root|root$" passwd | grep root

grep 'r..t' test #匹配r和t 之间有两个字符的;有几个点就有几个字符
grep 'r*t' test  #匹配r出现任意多次,并以t结尾的行
grep -E 'ro*t' text #匹配r和t之间有任意多个o的行
grep -E 'ro?t' text #匹配r和t之间有零到一个o的行
grep -E 'ro{1,}t' text #匹配r和t之间有一到任意多个o的行
grep -E 'ro{3,7}t' text #匹配r和t之间有3到7个o的行
grep -E \(ro\){n\}ro text #匹配关键字ro出现n次
grep -E  '.*' text        #关键字之间匹配任意字符


1.3>grep 中的正则表达式
^westos #以westos开头
westos$ #以westos结尾
'w....s' #w和s之间由四个字符
'w.....' #w后由五个字符
'.....s' #s之前有五个字符

1.4>grep中字符的匹配位置设定
^关键字
关键字$
\<关键字
关键字\>
\<关键字\>
1 grep -E 'rt' text
2 grep -E 'r*t' text
3 grep -E 'r.*t' text
4 vim text
5 grep -E  "r...." text
6 grep -E  "r....\" text
7 grep -E  "....t" text
8 grep -E  "\<....t" text
9 ifocnfig eth0 | grep -E "inet\>" #用grep显示本机ip

脚本实验:

写一个show_loginuser.sh 使其可以显示出能登陆shell的所有的用户

1 cd /mnt
2 vim show_loginuser.sh
#/bin/bash
SHELL=$(echo `grep -v nologin /etc/shells` | sed 's/ /|/g')
grep -E "$SHELL" /etc/passwd | cut -d : -f 1
3 chmod +x show_userlogin.sh
4 /mnt/show_userlogin.sh
测试新建一个用户看其是否被添加到列表中
1 useradd -s /bin/tcsh user1
2 su - user1
3 /mnt/show_userlogin.sh
4 cat show_userlogin.sh 

2 sed  行编辑器 stream editer

用来操作纯ASCII码的文本处理时,把当前处理的行村数在临时缓冲区中,称为"模式空间"(pattern space)可以指定仅仅处理哪些行
sed 符合模式条件的处理不符合条件的不予处理,处理完成之后把缓冲区的内容送往屏幕,接着处理下一行,这样不断重复,直到文件末尾
实验操作:

1  cat /etc/shells
2  grep nologin /etc/shells
3  echo `grep nologin /etc/shells`
4  echo `grep nologin /etc/shells` | sed 's/ /**/g'

2.1>Sed 命令格式

  调用sed 命令有两种格式
  sed [opinions参数] 'command'命令 file(s)
  sed [opinions]   -f scriptfile file(s)

2.2>sed对字符的处理
p   显示
d   删除
a   添加
c   替换
w   写入
i   插入
2.3>p模式操作
 1  cp /etc/fstab /mnt/
 2  sed -n '/^#/p' fstab #显示以#开头的行
 3  sed -n '/^#/!p' fstab #不显示以#开头的行
 4  sed -n '/^UUID/p' fstab #显示UUID开头的行
 5  sed -n '/UUID$/p' fstab #显示UUID结尾的行
 6  sed -n '/1$/p' fstab    #显示1开头的行
 7  cat -n fstab | sed -n '2,6p' #显示2-6行
 8  cat -n fstab | sed -n -e '2p' -e '6p'#显示第二行和第六行
 9  cat -n fstab | sed -n -e '2p;6p' #显示第二行和第六行
10  cat -n fstab | sed -n -e '2!p'   #不显示第二行
11  cat -n fstab | sed -n -e '2,6!p' #不显示第二行到第六行
12  cat -n fstab | sed -n -e '2!p;6!p' | uniq -d #不显示第二行和第六行



脚本实验:

建立user1;user2;user3 密码分别user1123 user2123 user3123 脚本
1 vim userfile
2 vim passfile
sed -n '1p' userfile
sed -n '1p' passfile
wc -l userfile | cut -d " " -f 1
3 vim user_create.sh
#!/bin/bash
MAX_LINE=`wc -l $1|cut -d " " -f 1`
for LINE_NUM in `seq 1 $MAX_LINE`
do
    USERNAME=`sed -n "${LINE_NUM}p" $1`
    PASSWORD=`sed -n "${LINE_NUM}p" $2`
    useradd $USERNAME
    echo $PASSWORD | passwd --stdin $USERNAME
done
4 cat userfile
user1
user2
user3
5 cat passfile
user1123
user2123
user3123
测试运行脚本:
6 sh user_create.sh  userfile passfile
7 su - user1
8 su - user2
9 id user1
10 id user2
11 id user3

实验结果:

2.4>D模式操作:
1 cat -n fstab | sed -n -e '2,6!p' #不显示第二行到第六行
2 cat -n fstab | sed -n -e '2!p;6!p' | uniq -d #不显示第二行和第六行
3 cat -n fstab | sed -e "2d;6d" #删除第二行和第六行
4 cat -n fstab | sed -e "2,6d"  #删除第二行到第六行
5 cat -n fstab | sed -e '/^#/d' #删除#开头的行
6 sed -e '/^#/d' fstab #删除#开头的行    
7 sed -e '/^$/d' fstab #删除空行
8 sed -e '/^$/d;/^#/d' fstab #删除空行以及以#开头的行
9 sed -e '/UUID/d' fstab #删除有UUID 的行
10 sed -e '/UUID/!d' fstab #不删除有UUID 的行
11 sed -e '/^UUID/!d' fstab 不删除UUID开头的行


对比-p 和-d:

2.5>A模式
sed '/^UUID/a \hello'  fstab'
sed '/^UUID/a \hello sed\nwestos fstab'
1  vim westos
2  cat westos
3  sed '/linux/ahello' westos #在westos文件中给linux后添加hello
4  sed '/linux/a\hello' westos #在westos文件中给linux后添加hello
5  sed '/linux/ahello\nworld' westos #在westos文件中给linux后添加hello 换行添加world
6  sed '/linux/a hello world' westos #在westos文件中给linux后添加hello world
2.6>I 模式

7  sed '/linux/iworld\nwestos' westos #在linux之前插入world换行westos

2.7>W模式操作
 1  sed -n '/bash$/p' /etc/passwd > file #把/etc/passwd中以bash结尾的行追加到file中
 2  cat file
 3  rm -fr file
 4  sed -n '/bash$/wfile' /etc/passwd #把/etc/passwd中以bash结尾的行写入file中
 5  cat file
 6  sed '/linux/=;wfile' westos #把westos里的 linux写到file里面
 7  cat file
 9  sed '/linux/=' -i westos #i参数改变westos文件内容
10  cat westos
11  echo `sed '=' westos `
12  sed '=' westos
13  vim westos
14  sed '=' westos
15  echo `sed '=' westos `
16  sed '6r westos ' fstab #把westos里的内容写入fatab第六行中
 1  sed -n -e '/UUID/p' fstab
 2  sed -n -e '/UUID/p' -ne '/^UUID/=' fstab
 3  sed -n -e '/UUID/p;/^UUID/=' fstab
2.8>C模式

sed '/^UUID/c\hello' /etc/fstab#将/etc/fstab中UUID开头的行变成hello


2.9>sed 的其他用法
 1  cat fstab
 2  sed 'G' fstab #每行之间添加一个空行显示
 3  sed '$!G' fstab #除了最后一行每行之间添加一个空行显示
 4  sed -n '$p' fstab #显示最后一行
 5  sed '=' fstab | sed 'N;s/\n/ /g' #添加每行的行号


2.9>sed替换模式
1 cp /etc/passwd .
2 vim passwd
3 sed 's/nologin/westos/g' passwd #全文替换
4 sed '3,5s/nologin/westos/g' passwd #替换第三行到第五行
5 cat passwd
6 vim passwd
7 sed '/adm/,/sync/s/nologin/westos/g;s/sbin/lee/g' passwd #从/adm/到/sync/之间的行全文替换nologin为westos;并且全文替换sbin为lee
8 sed  -e '/adm/,/sync/s/nologin/westos/g;s/sbin/lee/g' passwd
9 vim file
  s/login/westos/g
10sed -f file passwd #替换,不更改原文件内容
11sed  -f file -i passwd #替换,更改原文件内容
12cat passwd 


脚本实验:

写一个脚本,当执行该脚本,会自动安装apache,并改变其端口为$1

echo -e "\033[35m\033[7mhello yuhan \033[0m"
echo -e "\033[颜色代码m\033[效果代码m 内容 \033[0m" [0m 表示执行完echo立即关闭
1  vim install_apache.sh
#!/bin/bash                  
yum install httpd.x86_64 -y &> /dev/null;
sed -i "/^Listen/cListen $1" /etc/httpd/conf/httpd.conf;
echo  -e "\033[33m\033[3mThe listen is changed; \033[0m"
sed -ne '42p' /etc/httpd/conf/httpd.conf
systemctl restart httpd
2  sh install_apache.sh 66
3  netstat -anp | grep 66 #测试查看66端口是否备httpd占用,即更改是否成功

显示本机ip

ifconfig eth0 | awk -F " " '/inet\>/{print $2}'
查看/etc/passwd中有多少行
awk -F  " "  'BEGIN{N=0}/.*/{N++}END{print N}' /etc/passwd
3 awk 报告生成器

  awk处理机制:awk会逐行处理文本,支持在处理第一行之前做一些准备工作,以及在处理完最后一行做一些总结性质的工作

在命令格式上分别体现如下:
 BEGIN{ }:读入第一行文本之前执行,一般用来初始化操作
  { }    :逐行处理,逐行读入文本执行相应的处理,是最常见的编辑指令块
 END{ }  :处理完最后一行文本之后执行,一般用来输出处理结果
3.1>awk基本用法:
 awk  -F ":" '{print 'NR==3'}' passwd
 以:为分隔符,打印第三行
 awk -F ":" 'BEGIN {print NAME}'{print $1}'  passwd
 以:为分隔符,处理前打印NAME,打印第一列
 awk  -F ":" 'BEGIN{print "NAME"}{print $1}END{NR}'  passwd
 以:为分隔符,处理前打印第一列,处理后打印NR行
 awk  '/bash$/ ' passwd
 以:为分隔符,打印以bash结尾的行
 awk  -F ":" '/bash$/{print $1}'  passwd
 以:为分隔符,打印以bash结尾的行的第一列
 awk 'BEGIN{a=34;print a+12}'
 打印34 到34+12
 awk  -F ":" '{print "NAME"}NR<=4&&NR>=1{print $1}' passwd
 以:为分隔符,处理前打印NAME,打印1-4行的第一个字符
awk -F ":"  '{ print $1}' passwd #以:为分隔符,打印第一列
awk -F ":"  'BEGIN{ print "NAME"}{print $1}' passwd #处理之前打印NAME,以:为分隔符打印第一列
awk '/bash$/{print}' passwd #打印以bash结尾的行
awk -F ":"  'BEGIN{N=0}/bash$/{N++}END{print N}' passwd #打印以bash结尾的行有多少行
awk '/^t|nologin$/{print}' passwd #打印以t开头的行或以no123结尾的行
awk '/^a|no123$/{print}' passwd #打印以a开头的行或以no123结尾的行
awk -F ":" '$1!~/^r/{print}' passwd #打印不以r开头的行
awk -F ":" '$7!~/no123$/{print}' passwd #打印不以no123结尾的行
awk -F ":" '{print NR,$0}' passwd #0表示所有
awk -F ":" '{print NR,$1}' passwd #以:为分隔符打印,第一列,并标示行数
awk -F ":" '$6!~/^\/home/&&/bash$/{print $1}' /etc/passwd #能登陆bash的用户,家目录
不在home
awk -F ":" 'BEGIN{N=0}/$6~/^/home/&&/bash$/{N++}END{print N}' /etc/passwd #能登陆bash的用户,家目录不>在home的用户数目




应用:

1.计算显示能够登陆系统的用户的个数

1 vim num_login.sh

#!/bin/bash

awk -F ":" 'BEGIN{N=0}//&&/bash$/{N++}END{print N}' /etc/passwd

2 sh num_login.sh

2.找出系统中可以登陆系统,但用户的家目录不在/home下
1 vim login_home.sh

#/bin/bash

awk -F ":" '$6!~/^\/home/&&/bash$/{print $1}' /etc/passwd

2 sh login_home.sh

3.显示本机ip
1>vim ip_show.sh
  #!/bin/bash
  ifconfig eth0 | awk -F " " '/inet\>/{print $2}'
2>sh  ip_show.sh


4.统计文件的行数

1 vim line_show.sh

#!/bin/bash                  
awk -F ":" 'BEGIN{N=0}//{N++}END{print N}' $1

2 sh line_show.sh FILENAME







 

猜你喜欢

转载自blog.csdn.net/dreamer_xixixi/article/details/80752237