2.1 正则表达式
在介绍 sed 和 awk 之前,首先需要介绍正则表达式的使用。
正则表达式(regular expression)是描述一种字符串匹配的模式,常用来检查一个字符串或文件中是否含有特定的字符串,以便对其进行替换、删除、插入等操作.很多编程语言都支持正则表达式,如:php、perl、phyton、java 等。在大多数编程语言中, 正则表达式都被括在两个正斜杠(/)之间,典型的形式是:
/pattern/
pattern 是由普通字符(数字、字母等)以及特殊字符(元字符)组成的字符串模式。
一,正则表达式基础
* 表示0个或多个在*字符之前的那个普通字符
如,helo,hello,helllllo都 可以用hel*o来表示.
ls -lh [0-9]*[a-z]*...
. 表示匹配任意字符
如, ...73. 前三个点为任意字符,最后一个点也是,sas73i,a d747都能匹配上述字符串(空格也算).
^ 表示匹配行首
如,^cloud表示匹配cloud开头的行.
结合*和.使用^...X86* 如876X86666
$ 表示匹配行尾
如,micky$
该正则表达式匹配micky结尾的所有行.
sed -i 's/^basedir=$/basedir=\/usr\/local\/mysql/g' /etc/init.d/mysqld
^$ 匹配所有空行
该正则表达式既匹配行首,又匹配行尾,中间没有任何字符.因此为空行。
^.$ 匹配包含一个字符的行
匹配最后一行
awk 'END {print}'
sed -n '$p'
[] 匹配任意字符
[0123456789]表示匹配任意数字。
[a-z]或[A-Z]表示匹配任意任意字母。
[^b-d]表示取反,表示匹配不在b-d范围(b,c,d)的所有字符.就是排除这三个字符.
[A-Za-z] [A-Za-z]*匹配任意字母
[a-h]*.awk匹配a-h并以.awk结尾的所有文件
[a-h]*.[^awk]* 匹配a-h开头的,并排除掉
\ 转义符号
\ 符号是转义字符用于屏蔽一个元字符的特殊意义。
\.后面的字符"."是元字符,经过转义后不再是元字符而是普通的句号
\<\>符号是精确匹配符号,
\<the\>精确匹配the这个单词。而不匹配包含the字符的单词如,there,them
\{\}系列符号(指定匹配出现的个数)
\{n\}:匹配前面字符出现n个。
JO\{3\}B#重复字符O 3个,匹配值JOOOB
\{n,\}:匹配前面字符至少出现n个
JO\{3,\}B#重复字符O 至少3个,匹配值JOOOB,JOOOOB
\{n,m\}#重复字符出现n到m个
JO\{3,6\}B#重复字符出现3到6个。匹配值JOOOB,JOOOOB
[a-z]\{5\}#精确匹配5个小写字母.
二,正则表达式扩展
? 符号
匹配"?"符号之前的那个字符0次或1次。
JO?B
+ 符号
匹配"+"符号之前的那个字符1次或任意次。
S+EU,SSEU、SSSSSEU
()符号和|符号
()被[]
| 也表示或的意思
()通常与|符号结合使用,表示一组可选字符的集合
re(a|e|o)d 表示在字符a,e,o中选择任意一个字符,read,reed,reod
re(a|e|o)d等价于re[aeo]d
SHELL本身不支持正则表达式,使用正则表达式的是SHELL命令和工具
grep sed awk等.
通配符
ls -lh [a-h]*.awk
ls -lh 0?.pem
ls -lh [a-h]*.[^awk]*
通配符中花括号表示一组表达式的集合
ls -l {[a-h]*.awk,0?.pem}
,逗号表示或的意思
sed命令基本用法文本处理器.(行处理器)
sed是一个非交互式文本编辑器,它可对文件和标准输入进行编辑,标准输入可以来自键盘,文件重定向,字符串,变量,甚至来自于管道的文本.
sed从文本的一个文本行或标准输入中读取数据,将其复制到缓冲区,然后读取命令行或脚本的第一个命令,对些命令的行号进行编辑,重复此过程直到命令行或脚本中的所有行命令都执行完毕.
sed命令用于以下三种场合
1,编辑村对交互式文本编辑而言太大的文件。
2,编辑命令太复杂,在交互式文本编辑器中难以输入的情况
3,对文件扫描一遍,但是需要执行多个编辑函数的情况。
sed只是对缓冲副本进行编辑,并不编辑原始文件.
要保存改动内容,需要交将输出重定向到别一个文件,如下命令
sed 'sed命令' input-file > result-file
调用sed三种方式
1,在shell命令行输入命令调用sed,格式为
sed [选项] 'sed命令' 输入文件
注意,需要用单引号将sed命令引起来
2,将sed命令插入脚本文件后,然后通过sed命令调用它,
sed [选项] -f sed 脚本文件 输入文件
3,将sed命令插入脚本文件后,最常用的方法是设置该脚本文件可执行,
然后直接执行该脚本文件。
./sed 脚本文件 输入文件
sed命令选项
-n 不打印所有行到标准输出
-e 表示将下一个字符串解析为sed编辑命令,如果只传递一个编辑命令给sed,-e选项省略。
-f 表示正在调用sed脚本文件
sed通常有定位文本行和sed编辑命令两部分组成。sed编辑命令对定位文本行进行各种处理。
sed 提供两种方式定位文本
1,使用行号,指定一行,或指定行号范围。
2,使用正则是表达式
sed 定位文本选项
x 为指定行号
x,y 指定从x到y的行号范围
/pattern/ 查询包含模式的行
/pattern/pattern/ 查询包含两个模式的行
/pattern/,x 从与pattern的匹配到x号行之间的行
x,/pattern/ 从x号行到与pattern的匹配行之间的行
x,y! 查询不包括x到y行号的行
sed编辑命令选项
对文本处理如打印,删除,追加,插入,替换等
p 打印匹配行
= 打印文件行号
a\ 在定位行号之后追加文本信息
i\ 在定位行号之前插入文本信息
d 删除定位行
c\ 用新文本替换定位文本行
s 使用替换模式替换相应模式
r 从另一个文件中读文本
w 将文本写入到一个文件
y 变换字符
q 第一个模式匹配完成后退出
l 显示与8进制ASCII码等价的控制字符
{} 在定位行执行的命令组
n 读取下一个输入行,用一个命令处理新的行
h 将模式缓冲区的文本复制到保持缓冲区
H 将模式缓冲区的文本复制到保持缓冲区
x 互换模式缓冲区和保持缓冲区的内容
g 将保持缓冲区的内容复制到模式缓冲区
G 将保持缓冲区的内容追加到模式缓冲区
i 在原文件上修改
sed命令选项的一组例子
sed -n 选项
不打印所有行,不加-n打印所有行.
sed '1p' input
打印第一行
sed -n '1p' input
打印范围行3,6行
sed -n '3,6p' input
打印匹配关键字的行(对大小敏感)
sed -n '/certificate/p' input
sed -e选项
有多个sed编辑命令才有用武之地
sed -n -e '/Certificate/p' -e '/Certificate/=' input
注意,不支持同时带多个编辑命令的用法如:
sed [选项] -e 编辑命令1 -e 编辑命令2 ... -e 编辑命令n 输入文件
sed -f 选项
-f选项只有调用sed脚本文件时才起作用,追加文本,插入文本,删除文本和替换文本等功能需要几条sed命令来完成,所以将这些命令写入sed脚本,然后调用sed脚本来完成.
sed '指定地址a\text' 输入文件
sed '/file:/a\We a append a new line.' input
#vim append.sed
#!/bin/sed -f
/file:/a\
We a append line.\
We a append line.
#chmod u+x append
#./append.sed input
sed 文本定位的一组例子
匹配元字符
sed -n '/\./p' input
sed -n '/\$/p' input
使用元字符进行匹配
匹配最后一行
sed -n '$p' input
包含点bus结尾的行
sed -n '/.*bus/p' input
sed -n '1p' /etc/issue | awk '{pirnt $1,$3}'
!符号(不能用于关键字匹配如/pattern/)
匹配不在范围内的行
sed -n '2,10!p' input
使用行号与关键字匹配限定行范围
sed -n '/seugrid/,$p' input
sed基本编辑命令的一组例子
插入文本行前 'i\ 和a\行尾' 插入文本并换行.
sed '指定地址 i\text' 输入文件
sed '/file/i\file' files.txt ##指定行前插入文本并换行
sed '/file/a\file' files.txt ##指定行尾插入文本并换行
在文本的行首或行尾不换行插入字符.
sed 's/^/HEAD/g' files
sed 's/$/TAIL/g' files
在指定文本的行首或行尾不换行插入字符.
sed '/xx$/s//&,要插入的字符/g' files
sed 设置变量$Server_ip,需要使用双引号.
"/allowed_hosts=127.0.0.1$/s//&,$Server_ip/g" files
修改文本(整行都修改) 'c'
sed -i '/file/c\peng' files
2,5行替换成 No 2-5 number
sed -i '2,5c No 2-5 number' files
删除文本 'd'(整行)
sed '1d' input
sed '$d' input
sed '1,10d' input
删除匹配的行
sed '/world/d' filename
删除某行
sed '4,8d' thegeekstuff.txt
从第三行开始,每隔一行删除
sed 3~2d thegeekstuff.txt
删除最后一行
sed '$d' thegeekstuff.txt
删除与关键字匹配的行(不区分大小写)
sed '/[Cc][Ee][Rr][Tt][Ii][Ff][Ii][Cc][Aa][Tt][Ee]/d' file.txt
删除不在范围内的行
sed '2,10!d' file
删除空行
#ls | paste -d " " -s - - - - - | sed 's/ /\n/g' | sed '/^$/d' | wc -l
sed '/^$/d' thegeekstuff.txt
删除连续重复的行
sed '$!N; /^\(.*\)\n\1$/!P; D' file.txt > new_file
替换文本 'g'
g 表示替换文本中所有出现被替换字符串之处
p 与-n选项结合,只打印替换行
w文件名 表示将输出定向到一个文件
格式如下
sed -n 's/被替换的字符串/新字符串/p' 输入文件
sed -n 's/Certificate/CERTIFICATE/p' input
sed -n 's/Certificate/CERTIFICATE/' input 不加p不打印匹配到的内容
过滤掉名号,逗号,冒号,空格转换换行,对每行第一个单词排序,输出重复出现的次数,按照频率从大到小排序.
sed 's/\.//g' -e 's/\,//g' -e '/\://g' -e 's/ /\n/g' "$1" | sort | uniq -c | sort -nr
替换整行
sed -i 's#^.*BASEDIR=\/usr\/local.*#BASEDIR=\/usr\/local\/services\/zabbix\/#g' /etc/init.d/zabbix_agentd
只替换第一处的匹配到关键字
sed 's/seu/njeu/p' input
替换多处匹配到关键字g选项才发挥作用
sed -n 's/seu/njeu/pg' input
sed在这个文里Root的一行,匹配Root一行,将no替换成yes
sed -i '/Root/s/no/yes/' /etc/ssh/sshd_config
指定替换第几处的关键字
sed -n 's/seu/njeu/2p' input
sed替换多个字符串
sed -i 's/7778/80/g;s/7779/443/g' /etc/apache2/ports.conf
w选项将输出重定向到这个文件
sed -n 's/seu/njeu/pw ouput' input
&符号可用来保存被替换的字符串以供调用
sed -n 's/seu/(&)/pg' input
写入一个新文件 'w'
1到5行写入新的文件
sed -n '1,5 w output' input
将globus关键字写入新的文件
sed -n '/globus/w output' input
从文件中读入文本 'r'
在匹配行的行后读入otherfile文件
sed '/Certificate/r otherfile' input
退出命令 'q'
匹配到第一个就退出
sed '/.r.*/p' input
sed截取字符
提取
str="abcdefg"
echo "$str" | sed -r 's/.*c(.*)f.*/\1/' ##1表示提取括号中的字符
grep '127.0.0.1' a.txt |sed -r 's/.*tb_tow(.*)\?.*/\1/'
变换命令 'y'
对文本逐个字符变换,变换字符长度要一样.
sed 'y/fmj/FMJ/' imput
sed显示控制字符 字母'l'
sed -l 显示文件中的控制字符
sed -n '1,$l' control
在定位行执行命令组(类似于-e)
sed -n -e '/Certificate/p' -e '/Certificate/=' input
等价于
sed -n '/Certificate/{p;=}' input
i替换成I,le替换成99.
sed '/Certificate/{s/i/I/pg;s/le/99/;}' input
sed中使用变量(双引号)
sed -in-place "s/8080/$port/g" /home/work/server.xml