一起学Shell之(三) 查找与替换


述:正则表达式可以提供更强大的标记法,以单个表达式匹配各种实际的文本数。
 
grep家族的武器强度。
----------------------------
grep:文本匹配程序
egrep:使用扩展正则表达式,消耗更多的运算资源
fgrep:快速grep,匹配固定字符串而非正则表达式。
-----------------------------
who |grep -F root
注:-F是grep默认的选项,列出单前root登陆的信息,过程就是把who打印出来的信息交给grep,grep查找root的行。然后再打印出来。
grep 选项 文件
用途:显示一个或多个模式的文本行,通常用于管道|的第一步。具体参数请查找相关资料。
 
这个就不用多说了吧,用途大大的,各种查找,与sed awk cut组成强大的陈营。一起学下去肯定会得到更多。下一步找个Shell分析一下。
 
正则表达式:是一种表达方式,让你可以查找匹配的特定准则的文本,例如表达以"a字母开头“匹配多个字符。
 
说白了,就是以特定的语言来规定内在的命令,就好像你在北京用家乡话和老乡沟通一样,别人听不懂的。听的懂的人就可以执行相关的命令了。但是搞IT的都喜欢弄些专业的名词来更好的表述自己的观点。
 
正则是由两个基本组成部分建立,一般字符和特殊字符,一般就是没有意义的字符,特殊就是有特别意义的字符就好像你的家乡话一样,又称元字符。
 
正则支持的命令有:
查找相关:grep egrep agrep 
编辑器:sed 
字符串处理程序:awk icon perl python ruby tcl 
文件查看程序:more page pg less 
文件编辑程序:vi emacs jed jove vile vim等
 
编写正则表达式的三个步骤:
1、知道要匹配的内容以及它如何出现在文本中。
2、编写一个模式来描述要匹配的内容。
3、测试模式来查看它的匹配内容
 
正则表达式产生的后果:
Hit命中 
Misses非命中
omissions遗漏
false alarms假命中
 
粗俗的来讲就是你首先要需要你的需求以及怎么设计需求,最后预览一下看是不是和你的需要的一样。而产生的后果也就只有这么几种。可以根据错误往上查。
 
 
 
元字节查看图
 
------------------------------------------------
 
-------------------------------------------
 
看了表之后余下的就是多练习了,查看时必须先根据前优先级然后再查看,不然真的看晕你。大框架里包小框架,等下sed里会有,我多写一点实例。
 
优先级: 高至低
[....] [: :] 方括号符号
[ ]     方括号表达式
\( \) \digit  子表达式或反向应用
* \ & \ }    前置单个字符发现的正则表达式
无符号     连续
^$           锚点
 
你可以看不懂正则,但一定要记住优先级,不然你查表都没法查。
 
流编辑器Sed
    解释:shell中处理一般文件替换支持正则表达式与替换文本,任何可显示的字符都可以作为定界符,通常以标点符号作为分界符
 
如 sed 's/a/b/' file 作用是把file文件中的第一个a替换成b 那么上方的定界符解释是什么意思呢?
看这个你就明白了,sed's/a/b/' file 等同于 sed'#s#a#b' file 定界符就是这个意思,这里得感谢dn833的指导,在sed中'与"都可以使用,意思就是说sed"s/a/b/' file也可以使用。 
 
使用方法:
[address] command
替换:[address] s/pattern/replacement/flags
 
标记flages有:
-n 可以是1-512,表示第n次出现的替换情况
g  全局更改,就是全部替换的意思 sed 's/a/b/g' file 后面那个g也就是flages全部替换。
p  打印模式之间的内容
w file 写入到一个文件file中
 
 
 
 
 
下面有很多的实例:
 
------------------------------------------------
查看文件
[root@localhost sed]# cat file
a a a a a
a 
b b b b bb
b
c c c c c 
c
ddd dd d d d 
d

 

 
替换第一个'无空格a'为b
[root@localhost sed]# sed 's/a/b/' file 
b a a a a
b 
b b b b bb
b
c c c c c 
c
ddd dd d d d 
d

 

 
替换全部的a为b g表示全部替换
[root@localhost sed]# sed 's/a/b/g' file 
b b b b b
b 
b b b b bb
b
c c c c c 
c
ddd dd d d d 
d

 

 
替换第一个'空格a'和'空格c',其中;是分隔符
[root@localhost sed]# sed 's/ a/, b/ ; s/ c/,d/' file
a, b a a a
a 
b b b b bb
b
c,d c c c 
c
ddd dd d d d 
d
--------------------------------------------

 

 
替换' " [ ] \ / .等符号
替换'有点不同
-------------------------------------------
[root@localhost sed]# sed 's/'\''/b/g' file
a a a a a
a 
b b b b bb
b
c c c c c 
c
ddd dd d d d 
d
a a aa a
a
b " " " "
" ""
\\\\//[]
b bb bb b b
[root@localhost sed]# 

 

 
替换其它的[ ]< >等
[root@localhost sed]# sed 's/\[/b/g' file
a a a a a
a 
b b b b bb
b
c c c c c 
c
ddd dd d d d 
d
a a aa a
a
' " " " "
" ""
\\\\//b]
' '' '' ' '

[root@localhost ~]# 

 

 
正则一例:
[root@localhost sed]# cat z
a:b
c:d
e:f
[root@localhost sed]# sed 's/\(.*\):\(.*\)/\2:\1/' z
b:a
d:c
f:e

 

 
如何来看这个正则呢? sed 's/\(.*\):\(.*\)/\2:\1/' z
首先看大框框sed's/?a/?b/' 可以分为两部分了,?a=\(.*\):\(.*\) ?b=\2:\1 这样是不是就可以看清了?解释?a,
\)就是相关的意思,正的变负的负的变正的,所以这里要这么理解\(,把一般字符(换成特殊字符,才能组成正则嘛,后面都一样,  .* 看表后会发现.是任意一个字符,*是任意多个前面的字符,.*就是任意多个字符,现在看?b \2:\1
前面说了\正的搞成反的,在sed里2和1都是一般字符,这里反过来就是特殊字符也就是第一段和第二段,第二段是?a的后面那个.* \1是前面那个.* 所以是不是正好反过来了。看正则先看大框架再看优先级。看的多了就知道看了。
 
册除空行和带#号的这一行,我自己写的,用sed -e也可以。
[root@localhost sed]# sed '/^$/D' /etc/vsftpd/vsftpd.conf |sed '/\#.*/D'
anonymous_enable=YES
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
listen=YES
pam_service_name=vsftpd
userlist_enable=YES

 

 
sed '/^$/D' /etc/vsftpd/vsftpd.conf |sed '/\#.*/D' 再拆呗,sed '//D是册除的写法,具体可看sed表。^$ ^是以这个为开头,$以这个为结尾,开头结尾那就是空行咯,所以空行全册掉。 后面那个\#.* #不管在sed里还是正则里都没任何用,所以#.*也可以,我们可以更好的写^#.*来实现。这个要配置文件中相当重要,别人要看你的配置文件,你给他成百上千的行给别人看?
sed -e方式
[root@localhost sed]# sed -e '/^$/D' -e '/\#.*/D' /etc/vsftpd/vsftpd.conf 
anonymous_enable=YES
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
listen=YES
pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES

 

 
把单个数据替换成单个字母,这个可不是全局匹配哇。1和a 2b 3c等进行替换。
[root@localhost sed]# cat number
123456
123654
[root@localhost sed]# sed 'y/123456/abcdef/' number 
abcdef
abcfed
 
册除::d命令
sed '2d' file 册除file第二行 
sed '2,$d' file 册除2到最后那行
sed '$d'  file 册除最后一行
sed '/test/'d file 册除file中包含test的行。
sed '/a/b/'d file 册除a到b中间的行。
万变不离其宗,你掌握了规则,他再变也就是变下实例,其实吖根本就没变。
----------------------------------------------
 
 
CUT
解释:用来剪下文本文件中的数据,可以是字段类型和字符类型,一个制表字符为单个字符。
用法:cut -c list [file...]
      cut -f list [-d delim] [file...]
-c 以字符为主 
-d 定界符
-f 以字符为主
 
实例:
cut -d: -f 1,5 /etc/passwd   剪掉以:号为定界符的第1个和第5个然后打印出来,
/etc/passwd文件内容太多了,直接看这个吧。
---------------------------------------
[root@localhost sed]# echo 1:2:a:e:l:6|cut -d: -f 1,4
1:e
root@localhost sed]# 
------------------------------------------------------
 
JOin
解释:可以将多个文件结合在一起,每个文件里的每条记录都共享一个健值,健值指的是主字段。
语法:join [options...] file1 file2
 
转换过程如下:
----------------------------

[root@localhost sed]# cat 1
a 1 
b 2
c 4
d 4
[root@localhost sed]# cat 2
a 2
b 4
c 8
d 9

[root@localhost sed]# join 1 2
a 1  2
b 2 4
c 4 8
d 4 9
[root@localhost sed]# 
----------------------------------

 

这个合并数据用不错。积累命令吧,积累多了你就是个宝库了。
 
 
Awk 
解释:读取命令上所指定的各个文件(若无,则标准输入),一次读取一条记录(行)再针对每一行应用程序所指定的命令。
...|awk '{print some-stuff}'|...
 
sed和awk是个大话题不可能一下讲过,所以原书上只讲了一部分,在后面有单独讲这个的。
 
awk '{print $1}' 打印第一个程序
awk '{print $1,$5}' 打印2-5个字段
awk '{print $1,$NFS}' 打印1到最后  这个打印出来没回车
awk 'NF>0 {print $0}' 打印1到最后 这个打印可来有回车
 
 
awk -F: '{print $1,$5}' 以:为定界符打印第一个字段和第五个字段。是不是和cut一样,我们试下吧。
-----------------------------
[root@localhost sed]# echo "a:b:c:d:e:f" |awk -F: '{print $1,$4}'
a d
[root@localhost sed]# echo "a:b:c:d:e:f" |cut -d: -f 1,4
a:d
---------------------------------

 

基本没区别,但是中间有个:号,下面也会讲到的。
 
awk -F: -v'OFS=**' 'print $1,$4' file 这个是以**为来做分隔符啦,我们再试下。
---------------------------
[root@localhost sed]# echo "a:b:c:d:e:f" |awk -F: -v 'OFS=:' '{print $1,$4}' 
a:d
[root@localhost sed]# 
--------------------------------------

 

注意OFS=:'后面要加个空格,和'{分开。

相关内容

    暂无相关文章