shell编程入门(二)

查找和替换

查找文本

grep查找文本是相当方便的。

传统上有三种程序,可以用来查找整个文本文件。

  1. grep

    最早的文本匹配程序。使用POSIX定义的基本正则表达式(Basic Regular Expression,BRE)

  2. egrep

    扩展式grep(Extended grep)。使用扩展的正则表达式(Extended Regular Expression,ERE)

  3. fgrep

    快速grep(Fast grep)。匹配固定的字符串而非正则表达式,使用了优化的算法,能更有效的匹配固定的字符串。

但是POSIX标准已经将上面的三种合并为一个grep,它的行为通过不同的选项加以控制。-E指定是egrep,-F指定是fgrep。

简单的grep

  1. 语法

    grep [options ...] pattern-spec [ file ... ]

  2. 用途

    显示匹配一个或者多个模式的文本行。时常会作为管道的第一步,以便对匹配的数据进行进一步的处理。

  3. 主要选项

    -E  取代egrep
    -F  取代fgrep
    -l  列出匹配模式的文件名称,而不是打印匹配的行
    -i  模式匹配式忽略大小写的差异
    -q  如果模式匹配成功,则grep会成功离开,不讲匹配的行写入标准输出,否则即使不成功。
    -s  不显示错误信息,通常与-q并用
    -v  显示不匹配的行
正则表达式

正则表达式是一种表示方法,让你可以查找匹配特定准则的文本。

  1. POSIX方括号表达式
基本正则表达式
  1. 匹配单个字符
  2. 向后引用(backreference)

    匹配于正则表达式匹配的先前的部分。使用向后引用的步骤有二:

    1. 将子表达式包围在\(\)里,单个模式里可包括至多9个子表达式,且可为嵌套结构。
    2. 在同一模式之后是用\digitdigit指的是介于1到9之间的数字,指的是“匹配于第n个先前方括号内子表达式匹配成功的字符”。
  3. 单个表达式匹配多字符
  4. 文本匹配锚点

    1. 脱字符号(^):针对要被匹配字符串的开始处进行匹配。
    2. 货币符号($):针对要被匹配字符串的结尾处进行匹配。
  5. BRE运算符的优先级,由高至低

    运算符表示的意思
    [..][==] [::]用于字符排序的方括号符号
    \metacharacter转义的meta字符
    []方括号表达式
    \( \) \digit子表达式与向后引用
    * \{ \}前置单个字符重现的正则表达式
    无符号连续
    ^ $锚点
扩展的正则表达式
  1. 匹配单个字符
  2. 向后引用不存在
  3. 单个表达式匹配多字符
  4. 交替(alternation)

    方括号易于表示“匹配于此字符,或者其他字符,或……”,但不能指定“匹配于这个序列,或者其他序列,或……”。要达到后者的目的,可以使用交替运算符。即垂直的一条线,或者称为管道字符(|)。例如:grep -E name|echo devtty.sh

  5. 分组

    圆括号提供分组功能。例如:(why)+匹配多个why。

  6. 停驻文本匹配

    1. 脱字符号(^):针对要被匹配字符串的开始处进行匹配。
    2. 货币符号($):针对要被匹配字符串的结尾处进行匹配。
    3. 区别于BRE:在ERE中^$永远是meta字符。
  7. ERE运算符的优先级,由高至低

    运算符表示的意思
    [..][==] [::]用于字符排序的方括号符号
    \metacharacter转义的meta字符
    []方括号表达式
    ( )分组
    * + ? {}重复前置的正则表达式
    无符号连续
    ^ $锚点
    ``

正则表达式类型

其他详细的正则表达式用法请参考我的另一篇博客:正则表达式用法

在文本文件中进行替换

最佳的执行文本替换的程序应该是:sed—流编辑器(Steam Editor)。

基本用法

通常会在管道中间会用sed,以执行替换操作。

  1. 语法

    sed [-n] 'editing command' [file ...]
    sed [-n] -e 'editing command' ... [file ...]
    sed [-n] -f script-file ... [file ...]
  2. 用途

    为了编辑它的输入流,将结果输出到标准输出。

  3. 主要选项

    1. -e 'editing command'

      将editing command用到输入数据上,当有多个命令需要应用时,就必须使用-e 了。

    2. -f script-file

      自script-file文件中读取编辑命令。当有多个命令需要执行时,相当有用。

    3. -n

      不是每个最后已修改结果行都正常打印,而是显示以p指定的行。

  4. 动作:
    1. a append:增加,在当前行的下一行增加
    2. c:取代,取代n1到n2之间的行
    3. d delete:删除
    4. i 插入,目前行的上一行插入
    5. p 打印,常常与-n使用
    6. s 取代,s/old/new/g
替换细节
  1. 在正则表达式或者替代文本中也能转义定界符。如:

    sed 's/\/home\/tolstoy\//\/home\/lt\//'

  2. 向后引用替换文本。表示:“从这里开始替换成匹配第n个圆括号里子表达式的文本”。如:

    echo ~/Desktop/temp/haha/test/ | sed 's;\(/haha\)/test/;\1/lt/;'

  3. &表示‘从此处开始替换成匹配于正则表达式的整个文本’。如:

    test.xml.old内容为:Alpha is not Beta!
    sed 's/Alpha is/& Alpha,/' < test.xml.old > test.xml
    test.xml的内容为:Alpha is Alpha, not Beta!
  4. 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!
  5. 指定一个数字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!
  6. 多个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!
  7. 如果有很多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选定字段
  1. 语法

    cut -c list [ file ...]
    cut -f list[ -d delim] [ file ...]
  2. 用途

    从输入的文本中选择一个或者多个或者一组字符,配合管道可以做进一步的处理。

  3. 主要选项

    -c
        以字符为主,执行剪下的操作,list为字符编号或者一段范围的列表(用逗号隔开)
    
    -f
        以字段为主,执行剪下的操作,list为字符编号或者一段范围的列表(用逗号隔开)
    
    -d delim
        通过-f选项,使用delim作为定界符,默认定界符为制表字符(Tab)
使用join连接字段

join命令可以将多个文件结合在一起,每个文件里的每条记录,都是共享一个键值

  1. 语法

    join [ options ...] file1 file2
  2. 用途

    以相同一个键值,将已存储文件内的记录加以结合。

  3. 主要选项

    -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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值