在 shell 编程中,常需要处理文本,这里介绍几个文本处理命令。

一、grep 命令

grep 命令由来已久,用 grep 命令来查找 文本十分方便。在 POSIX 系统上,grep 可以在两种正则表达式风格中选择一种(BRE 和 ERE),或是执行简单的字符串匹配。传统上,有三种程序可以用来查找整个文本文件:

1)grep:最早的文本匹配程序。使用 POSIX 标准定义的基本正则表达(Basic Regular Expression,BRE);

2)egrep:扩展 grep。使用扩展正则表达式(Extended Regular Expression,ERE);

3)fgrep:快速 grep。匹配固定字符串而非正则表达式,它使用优化的算法,能更有效地匹配固定字符串。

  在目前的 POSIX 标准中,这三个程序已经被整合成为一个程序 grep,通过对 grep 命令加以不同的选项进行选择控制。

  grep 命令由一个选项、一个要匹配的模式和要搜索的文件组成,语法如下: 

grep [options] PATTERN [FILES]

  如果没有提供文件名,则 grep 命令将搜索标准输入。grep 命令将会根据所提供的模式对文件进行匹配,发现匹配查找模式的行时,将该行显示出来。当 grep 命令同时搜索多个文件时,将会在搜索结果每一行前面加上文件名与一个冒号。grep 命令的主要选项如下:

选项 功能
-E 使用扩展正则表达式进行匹配(取代传统的 egrep 命令)
-F 使用固定字符串进行匹配(取代传统的 fgrep 命令)
-c   输出匹配行的数目,而不是输出匹配的行
-h 取消每个输出行的普通前缀,即匹配查询模式的文件名
-i 忽略大小写
-l 只列出包含匹配行的文件名,而不输出真正的匹配行
-v 对匹配模式取反,即搜索匹配不到的行
-n 输出行号

   用例子演示一下:

[tongye@localhost ~]$ grep -ni ROOT /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin

  该命令将会在 /etc/passwd 中查找有 root 的行,并将该行显示出来, -n 选项输出行号,-i 选项忽略大小写。

 

二、sed 命令

  sed( stream editor 流编辑器) ,可以用来在管道或者命令序列中编辑数据。sed 的语法如下:

sed option command file

  其中,command 是命令部分,用来指示 sed 该执行何种操作,file 则是 sed 命令将要操作的对象,通常是一个文件,如果没有文件,则使用标准输入。option 是 sed 命令可以使用的选项,主要有三个选项: -n、-e、-f,在后面再介绍。

  sed 命令读取每一个文件,一次读一行,将读取的行放到内存的一个区域--称为模式空间(pattern space),所有编辑上的操作都会应用到模式空间的内容。当所有操作完成后,sed 命令会将模式空间的最后内容打印到标准输出,再回到开始处,读取另一个输入行。为了演示 sed 命令,笔者写了一小段文本 test.txt 用作试验的素材(英语差,语法问题请忽略)

hello,my name is tongye
I want to write a program named HelloWorld.c
now,let`s begin
#include "stdio.h"
main(){
        printf("Hello world");
}
oh,it`s symple
writed by tongye
end

2.1  使用 s 参数执行替换操作

  sed 命令一个常用的功能是进行替换操作,sed 替换操作的一般格式如下:

sed 's/string1/string2/' file    # 将文件中每行的第一个 string1 替换成 string2

  在上述语句中,参数 s 表示这是一个替换操作,/ 字符是界定符,用于分隔正则表达式与替代文本。界定符可以是任何可显示的字符,但是 / 字符是最常用的界定符。另外,在处理文件名称时,一般使用分号、冒号或逗号作为界定符。string1 是被替换的文本,可以是正则表达式;string2 是替换文本。

[tongye@localhost Shell_Program]$ sed 's/tongye/ttyezi/' test.txt 
hello,my name is ttyezi
I want to write a program named HelloWorld.c
now,let`s begin
#include "stdio.h"
main(){
        printf("Hello world");
}
oh,it`s symple
writed by ttyezi
end

   需要注意的是,上述语句只能替换第一个匹配到的文本,若想要将每一个匹配到的文本都替换掉,需要在结尾加上 g 参数(global),即:

sed 's/string1/string2/g' file    # 将文件中所有的 string1 都替换成 string2

  如果需要删除文本中的一个字符串,可以在替换文本处不放入任何文本(即空)来实现,如下:

sed 's/string1//g' file               # 删除文件中所有的 string1

 

2.2 使用 -e 选项和 -f 选项同时执行多个编辑命令

  当 sed 后面需要同时接多个编辑命令的时候,需要使用 -e 选项。每一个编辑命令都使用一个 -e 选项,如:

[tongye@localhost Shell_Program]$ sed -e 's/tongye/ttyezi/g' -e 's/HelloWorld/helloworld/g' test.txt
hello,my name is ttyezi
I want to write a program named helloworld.c
now,let`s begin
#include "stdio.h"
main(){
        printf("Hello world");
}
oh,it`s symple
writed by ttyezi
end

  当需要编辑的项目很多时,如果把每一个编辑命令都接到 sed 后面,无疑会让代码很复杂,不易阅读且容易出错。这时,可以将所有的编辑命令都写进一个脚本,再使用 sed 搭配 -f 选项来操作:

# substitute.sed 存放着编辑命令 
s/tongye/ttyezi/g
s/HelloWorld/helloworld/g
s;^\(.\).*\1$;The first letter of this line is the same as its last letter;


[tongye@localhost Shell_Program]$ sed -f substitute.sed test.txt                                
hello,my name is ttyezi
I want to write a program named helloworld.c
The first letter of this line is the same as its last letter
#include "stdio.h"
main(){
        printf("Hello world");
}
oh,it`s symple
writed by ttyezi
end
View Code

相关文章:

  • 2022-12-23
  • 2021-11-23
  • 2021-07-20
  • 2021-12-19
  • 2022-12-23
  • 2022-12-23
  • 2021-08-03
  • 2021-09-02
猜你喜欢
  • 2021-04-04
  • 2021-04-16
  • 2021-12-20
  • 2021-12-06
  • 2022-12-23
  • 2022-12-23
  • 2021-12-14
相关资源
相似解决方案