shell中最核心的三个命令grep、sed、awk
其中,grep查找速度最快。
sed命令是修改文本和替换文本的最佳工具。(工作在内存)
sed是一种支持正则表达式的非交互式流编辑器(stream editor)
脚本中修改文本或者文本替换的最佳工具
sed工作在内存,有两个空间:
模式空间里处理一行内容后,会将这一行内容删除。加载第2行内容。
sed编辑器逐行处理文件,并将输出结果打印到屏幕上。sed命令将当前处理的行读入模式空间(pattern space)进行处理。sed在该行上执行完所有的命令后就将处理好的行打印到屏幕上(除非之前的命令删除了该行),sed处理完一行就将其从模式空间里删除,然后将下一行读入模式空间进行处理、显示。处理完文件的最后一行,sed便会结束运行。sed在临时缓冲区(模式空间)对文件进行处理,所以不会修改原文件,除非显示指明-i选项。
sed的语法命令格式:
sed的常用选项:
sed的常用编辑命令:
sed的p命令示例:
sed -n ‘1,2p’ 输入文件
sed -n '1,5p' /etc/passwd 显示2到3行
sed -n ‘10p' /etc/passwd 显示第10行
sed -n ‘$p’ /etc/passwd 显示最后1行
sed -n '2,+2p' /etc/passwd 显示234行
sed -n ‘3,100!p’ /etc/passwd 显示1到2行
sed -n '1p;3p;5p' /etc/passwd 显示1,3,5,行
sed 模式
PS:
#cat -n passwd|sed -n '1~2p'
显示单数行,~表示步长
#cat -n passwd|sed -n '0~2p'
显示偶数行
删除操作可以根据行号和模式匹配进行操作
sed '3,5d' /etc/fstab
删除3到5行
sed '/2/d' /etc/fstab
删除包含数字2的行
sed '/ext3/!d' /etc/fstab
除了包含ext3的行都删除
sed -r '/^$|^#/d' /etc/inittab
删除空行和注释
sed -e '/^$/d' -e '/^#/d' /etc/vsftpd/vsftpd.conf
sed '/^$/d ; /^#/d' /etc/vsftpd/vsftpd.conf
追加操作可以根据行号和模式匹配进行操作 :
sed '1a 1111111111111111' /etc/fstab
在第一行后面追加后面的字符串
sed '/boot/a 1111111111111' /etc/fstab
在包含boot的行下面追加后面的字符串
插入操作可以根据行号和模式匹配进行操作 :
sed '$i 1111111111111111' /etc/fstab
在最后一行前面插入后面的字符串
sed '/defaults/i 1111111111111' /etc/fstab
在包含defaults的行前面插入后面的字符串
更改整行操作可以根据行号和模式匹配进行操作
sed ‘/id:/c id:5:initdefault:' /etc/inittab
将id:所在的行整行替换成后面的字符串
sed '3c ONBOOT=no' ifcfg-eth0
将第三行改成后面的字符串
读入操作可以根据行号和模式匹配进行操作
sed ‘$r /etc/hosts' /etc/fstab
在fstab文件的末尾后面读入hosts文件的所有内容
df -h | sed '/dev\/sda1/r /etc/mtab‘
在/dev/sda1后面读入mtab文件的内容
写入文件操作可以根据行号和模式匹配进行操作
sed '1w abc.txt' /etc/passwd
将文件的第一行写到abc.txt(和r命令正好相反)
sed '/^#/!w abc.txt' /etc/inittab
将所有不是#开头的行都写入abc.txt
sed -r '/^#|^$/!w abc.txt' /etc/vsftpd/vsftpd.conf
将配置文件中除了空行和注释都写入abc.txt
所以,对于sed的w命令,建议使用grep命令,然后追加到文件。
格式:sed -n [行号或模式]s/查找内容/替换内容/[替换标记] 文件
替换操作可以根据行号和模式匹配进行操作
替换标记有四种
sed -n 's/root/ROOT/2p' /etc/passwd
将文件中每行的第2个root替换为ROOT
sed '/^id/s/3/5/' /etc/inittab
将文件中找到以id开头的行中的:3:替换成:5:(先用^id找出行)
sed '/^local_enable/s/YES/NO/' vsftpd.conf
禁止本地用户登陆
sed 's/:/\n/g' /etc/passwd
将文件中的:号替换为换行符
sed 's/bash/nologin/ ; s/sbin/bin/' /etc/passwd
将文件中bash替换成nologin,同时将sbin替换成bin
sed -n '2,10s/^/#/p' /etc/passwd
在2到10行前面加上注释
sed -n ‘s/$/?/p' /etc/passwd
在每行末尾加上问号
sed的s命令可以使用任意分隔符作为定界符
sed -n '/^hello/s|/bin/bash|/sbin/nologin|p' /etc/passwd
sed -n '/^hello/s:/bin/bash:/sbin/nologin:p' /etc/passwd
注意:
例:
sed 'G' passwd
在passwd文件的每行后面加空行。
=====1个例子来理解2个模式:
先查找huawei,如果符合条件就将这行的内容写到hold space里,接着执行G命令,就会将hold space里的内容追加到pattern space后面,然后输出到屏幕。
因为第一行是xiaomi,不符合/huawei/模式条件,所以不将xiaomi复制到hold space里,又因为hold space里开始时默认是空的,所以会在xiaomi后面添加一行空行。
第2行的内容刚好就是huawei,符合模块的条件,就将huawei这行复制到hold space里,替换了原来里面的空的内容。接着执行G命令,又将huawei追加到pattern space空间的后面,所以有2个huawei,后面的行以此类推。
#sed '/huawei/h;G' 1.txt
xiaomi
huawei
huawei
apple
huawei
samsung
huawei
......
1.sed取出/etc/passwd文件的第一列
2.sed将PATH环境变量中的冒号换成换行
3.sed将PATH环境变量斜杠/换成斜杠\
4.sed修改SELINUX配置文件从开启变成禁用(/etc/sysconfig/selinux)
5.去掉/etc/passwd文件中第二个地段的x
6.修改/etc/inittab文件里的3或者5修改为6
7.编写一个脚本实现修改ip地址:
7.1.提醒用户输入ip地址和子网掩码、dns、网关
7.2.需要判断新输入的ip地址是否有人使用,如果有人使用这个ip地址,就不能去修改ip,并且提示。
7.3.刷新网络服务,让新的ip地址生效。
答案:
1.# cat passwd|sed -r 's/(^[0-Z]+)(.*)/\1/' --》\1表示第一个标签
2.# echo $PATH|sed 's/:/\n/g'
3.# echo $PATH|sed -r 's/\//\\/g'
或者# echo $PATH|sed -r 's#/#\\#g'(以#作分界符)
4.# cat selinux|sed '/^SELINUX=/s/enforcing/disabled/g'
5.# awk -F: '{print $1":"$3":"$4":"$6":"$7}' passwd
或者:# awk -F: ' OFS=":"{print $1,$3,$4,$5,$6,$7}' passwd --》OFS指定分隔符
或者:# cat passwd|sed 's/:x:/::/g'
6.# cat inittab |sed -r '/^id/s/:[35]:/:6:/g'
7.
#!/bin/bash
read -p "Please input the ip:" IP
read -p "Please input the netmask:" MASK
read -p "Please input the dns server:" DNS
read -p "Please input the gateway:" GATEWAY
a=$(cat ifcfg-eth0|grep "IPADDR"|cut -d '=' -f2)
if [[ $IP == $a ]]
then
echo "The IP:$IP is exist!!!"
else
sed -i "{
/IPADDR/c IPADDR=$IP
/NETMASK/c NETMASK=$MASK
/DNS1/c DNS1=$DNS
/GATEWAY/c GATEWAY=$GATEWAY
}" /lianxi/ifcfg-eth0
echo "The IP is alter:$IP"
fi
&符号表示前面找到的模式匹配内容。
例:
# cat -n passwd|sed -n -r 's/[0-9]{3}/&0/p'
找出uid100~999的,在后面都加个0
标签:sed使用圆括号定义替换模式中的部分字符
标签可以方便在后面引用,每行指令最多使用9个标签
例:
用sed取出passwd里面的第一列
# cat passwd|sed -r 's/(^[0-Z]+)(.*)/\1/' --》\1表示第一个标签
执行结果:用第一个标签(^[0-Z]+)把前面符合第一个和第二个的全部取代。
例2:
用第2个标签(.*)把前面的符合第一个和第二个的全部取代。
# cat passwd|sed -r 's/(^[0-Z]+)(.*)/\2/'
注:\2表示第一个标签
例3:
# echo aaa bbb ccc|sed -r 's/([a-z]+) ([a-z]+) ([a-z]+)/\3#\2#\1/'
--》注意小括号之间有空格!!
ccc#bbb#aaa
#sed -i '/$a/s/$a/shuaige/' 2.txt
#cat 2.txt
meinv
meinv
meinv1
meinv1
(没变。替换失败。)
#sed -i "/$a/s/$a/shuaige/" 2.txt
#cat 2.txt
shuaige
shuaige
shuaige1
shuaige1
!
sed -r 's/(^[0-Z]+)(.*)/\1/' /etc/passwd
显示文件的第一列
sed -r 's/(^[0-Z]+)(.*)/\2/' /etc/passwd
删除文件的第一列
1.要求去掉 /etc/passwd每行前面的空格和数字。
法1:使用标签来替换
#cat -n passwd|sed -r 's/(\s+[0-9]+\s+)(.*)/\2/'
法2:使用正则去匹配,然后用空的内容去替换
#cat -n passwd|sed -r 's/\s+[0-9]+\s+//'
2.要求将/var/www/html/文件中的网络路径换成本地路径。
# cat passwd
http://www.baidu.com/news/23643.html
http://www.163.com/bbs/23545.html
http://www.sina.com/music/77.html
http://www.chinaitsoft.com/bbs/678.html
答案:
# cat passwd|sed -r 's#(^http://www\.(.*)+\.com)#/var/www/html#'
/var/www/html/news/23643.html
/var/www/html/bbs/23545.html
/var/www/html/music/77.html
/var/www/html/bbs/678.html