查找和替换
查找文本
grep查找文本是相当方便的。
传统上有三种程序,可以用来查找整个文本文件。
grep
最早的文本匹配程序。使用POSIX定义的基本正则表达式(Basic Regular Expression,BRE)
egrep
扩展式grep(Extended grep)。使用扩展的正则表达式(Extended Regular Expression,ERE)
fgrep
快速grep(Fast grep)。匹配固定的字符串而非正则表达式,使用了优化的算法,能更有效的匹配固定的字符串。
但是POSIX标准已经将上面的三种合并为一个grep,它的行为通过不同的选项加以控制。-E
指定是egrep,-F
指定是fgrep。
简单的grep
语法
grep [options ...] pattern-spec [ file ... ]
用途
显示匹配一个或者多个模式的文本行。时常会作为管道的第一步,以便对匹配的数据进行进一步的处理。
主要选项
-E 取代egrep -F 取代fgrep -l 列出匹配模式的文件名称,而不是打印匹配的行 -i 模式匹配式忽略大小写的差异 -q 如果模式匹配成功,则grep会成功离开,不讲匹配的行写入标准输出,否则即使不成功。 -s 不显示错误信息,通常与-q并用 -v 显示不匹配的行
正则表达式
正则表达式是一种表示方法,让你可以查找匹配特定准则的文本。
- POSIX方括号表达式
基本正则表达式
- 匹配单个字符
向后引用(backreference)
匹配于正则表达式匹配的先前的部分。使用向后引用的步骤有二:
- 将子表达式包围在
\(
和\)
里,单个模式里可包括至多9个子表达式,且可为嵌套结构。 - 在同一模式之后是用
\digit
,digit
指的是介于1到9之间的数字,指的是“匹配于第n个先前方括号内子表达式匹配成功的字符”。
- 将子表达式包围在
- 单个表达式匹配多字符
文本匹配锚点
- 脱字符号(
^
):针对要被匹配字符串的开始处进行匹配。 - 货币符号(
$
):针对要被匹配字符串的结尾处进行匹配。
- 脱字符号(
BRE运算符的优先级,由高至低
运算符 表示的意思 [..][==] [::]
用于字符排序的方括号符号 \metacharacter
转义的meta字符 []
方括号表达式 \( \) \digit
子表达式与向后引用 * \{ \}
前置单个字符重现的正则表达式 无符号 连续 ^ $
锚点
扩展的正则表达式
- 匹配单个字符
- 向后引用不存在
- 单个表达式匹配多字符
交替(alternation)
方括号易于表示“匹配于此字符,或者其他字符,或……”,但不能指定“匹配于这个序列,或者其他序列,或……”。要达到后者的目的,可以使用交替运算符。即垂直的一条线,或者称为管道字符(
|
)。例如:grep -E name|echo devtty.sh
分组
圆括号提供分组功能。例如:
(why)+
匹配多个why。停驻文本匹配
- 脱字符号(
^
):针对要被匹配字符串的开始处进行匹配。 - 货币符号(
$
):针对要被匹配字符串的结尾处进行匹配。 - 区别于BRE:在ERE中
^
和$
永远是meta字符。
- 脱字符号(
ERE运算符的优先级,由高至低
运算符 表示的意思 [..][==] [::]
用于字符排序的方括号符号 \metacharacter
转义的meta字符 []
方括号表达式 ( )
分组 * + ? {}
重复前置的正则表达式 无符号 连续 ^ $
锚点 ` `
其他详细的正则表达式用法请参考我的另一篇博客:正则表达式用法
在文本文件中进行替换
最佳的执行文本替换的程序应该是:sed—流编辑器(Steam Editor)。
基本用法
通常会在管道中间会用sed,以执行替换操作。
语法
sed [-n] 'editing command' [file ...] sed [-n] -e 'editing command' ... [file ...] sed [-n] -f script-file ... [file ...]
用途
为了编辑它的输入流,将结果输出到标准输出。
主要选项
-e 'editing command'
将editing command用到输入数据上,当有多个命令需要应用时,就必须使用
-e
了。-f script-file
自script-file文件中读取编辑命令。当有多个命令需要执行时,相当有用。
-n
不是每个最后已修改结果行都正常打印,而是显示以p指定的行。
- 动作:
- a append:增加,在当前行的下一行增加
- c:取代,取代n1到n2之间的行
- d delete:删除
- i 插入,目前行的上一行插入
- p 打印,常常与-n使用
- s 取代,s/old/new/g
替换细节
在正则表达式或者替代文本中也能转义定界符。如:
sed 's/\/home\/tolstoy\//\/home\/lt\//'
向后引用替换文本。表示:“从这里开始替换成匹配第n个圆括号里子表达式的文本”。如:
echo ~/Desktop/temp/haha/test/ | sed 's;\(/haha\)/test/;\1/lt/;'
&
表示‘从此处开始替换成匹配于正则表达式的整个文本’。如:test.xml.old内容为:Alpha is not Beta! sed 's/Alpha is/& Alpha,/' < test.xml.old > test.xml test.xml的内容为:Alpha is Alpha, not Beta!
g
表示‘全局性,代替文本取代正则表达式中每一个匹配’。如果没有设置,那么只会替换第一个匹配。如:test.xml.old内容为:Alpha is Alpha! 未指定参数g: sed 's/Alpha/Beta/' < test.xml.old > nog.xml nog.xml的内容为:Beta is Alpha! 指定参数g: sed 's/Alpha/Beta/' < test.xml.old > g.xml g.xml的内容为:Beta is Beta!
指定一个数字n:表示替换第n次匹配到的内容。如:
test.xml.old内容为:Alpha is Alpha! 指定参数n=2: sed 's/Alpha/Beta/2' < test.xml.old > number.xml number.xml的内容为:Alpha is Beta!
多个sed,可以通过管道串联,也可以通过指定
-e
来实现。如:test.xml.old内容为:Alpha is not Beta! sed -e 's/i/I/g' -e 's/n/N/g' < test.xml.old > test.xml test.xml的内容为:Alpha Is Not Beta!
如果有很多sed要在一条命令执行就很恐怖了,可以采取参数
-f
。如:“`
test.xml.old内容为:Alpha is not Beta!
capital.sed的内容为:
sed ‘s/i/I/g’
sed ‘s/n/N/g’使用
-f
命令如下:
sed -f capital.sed test.xml.old > test.xml
test.xml的内容为:Alpha Is Not Beta!
“`
字段处理
一条记录(record)指相关信息的单个集合。字段(field)记录的组成部分。
使用cut选定字段
cut命令用来截取文本文件中的数据,文本文件可以是字段类型或字符类型。
使用cut选定字段
语法
cut -c list [ file ...] cut -f list[ -d delim] [ file ...]
用途
从输入的文本中选择一个或者多个或者一组字符,配合管道可以做进一步的处理。
主要选项
-c 以字符为主,执行剪下的操作,list为字符编号或者一段范围的列表(用逗号隔开) -f 以字段为主,执行剪下的操作,list为字符编号或者一段范围的列表(用逗号隔开) -d delim 通过-f选项,使用delim作为定界符,默认定界符为制表字符(Tab)
使用join连接字段
join命令可以将多个文件结合在一起,每个文件里的每条记录,都是共享一个键值
语法
join [ options ...] file1 file2
用途
以相同一个键值,将已存储文件内的记录加以结合。
主要选项
-1 field1 -2 field2 标明要结合的字段。-1 field1指的是从file1中取出field1,而-2 field1指的是从file2中取出field2。字段编号自1开始,而非0. -o file.field 输出file文件中的field字段,一般的字段则不打印。除非使用多个-o选项,即可显示多个输出字段。 -t separator 使用separator作为输入字段分割字符,而非使用空包空白。此字符也为输出字段分隔字符。
使用awk重新编排字段
取出字段并进行编排。
字段
awk设计的重点就在字段与记录上:awk读取输入记录,然后自动将各个记录切分为字段。
用法:awk '{ print $1 }
$0表示整条记录
设置字段分隔字符
可以使用-F选项设置读入分隔字符。
awk -F: '{ print $1, $5}' /etc/passwd
awk的输入、输出分隔字符用法是分开的。可以用OFS
变量,改变输出字段分隔字符。方式:在命令行里使用-v选项。
awk -F: -v 'OFS=/' '{ print $1, $5}' /etc/passwd
打印行
awk '{ print }'
等同于 awk '{ print $0}'
也可以输出一句话
awk '{ print "hello", $1 ,"!"}'
参考资料:
Shell脚本学习指南 作者:(美)罗宾著
备注:
转载请注明出处:http://blog.csdn.net/wsyw126/article/details/53100881
作者:WSYW126