linux高级原5

来源:互联网 发布:java ioc容器 编辑:程序博客网 时间:2024/06/05 08:06
shell脚本语言包含了众多用于解决Unix/Linux系统问题必不可少的组件。文本处理是shell脚本擅长的重要领域之一。它可以与sed、awk、grep、cut这类优美的工具组合在一起来解决文本处理相关的问题。

有各种各样的工具能够帮助我们从不同的细节层面上处理文件,比如字符、行、单词、行列等,允许我们用多种方法来处理文本文件。正则表达式是模式匹配技术的核心。借助适合的正则表达式,可以生成我们所需的各类输出结果,例如过滤、剥离(strip)、替换、搜索等。

使用正则表达式

正则表达式是由字面文本和具有特殊意义的符号组成的


正则表达式 描 述 示 例




2、用grep 在文件中搜索文本

在文件中进行搜索是文本处理中一项重要工作。我们也许需要在某些多达上千行的文件中查找所需要的数据。这则攻略将教你如何从大量数据中定位符合规格的数据。

grep命令作为Unix中用于文本搜索的神奇工具,能够接受正则表达式,生成各种格式的输
出。除此之外,它还有大量有趣的选项。让我们看看具体的用法。
(1) 搜索包含特定模式的文本行:

$ grep pattern filename
this is the line containing pattern
或者
$ grep "pattern" filename
this is the line containing pattern
(2) 也可以像下面这样从stdin中读取:
$ echo -e "this is a word\nnext line" | grep word
this is a word
(3) 单个grep命令也可以对多个文件进行搜索:
$ grep "match_text" file1 file2 file3 ...
(4) 用--color选项可以在输出行中着重标记出匹配到的单词:
$ grep word filename --color=auto
this is the line containing word
(5) grep命令只解释match_text中的某些特殊字符。如果要使用正则表达式,需要添
加-E选项——这意味着使用扩展(extended)正则表达式。或者也可以使用默认允
许正则表达式的grep命令——egrep。例如:
$ grep -E "[a-z]+" filename
或者
$ egrep "[a-z]+" filename
(6) 只输出文件中匹配到的文本部分,可以使用选项 -o:
$ echo this is a line. | egrep -o "[a-z]+\."
line.
(7) 要打印除包含match_pattern行之外的所有行,可使用:
$ grep -v match_pattern file
选项-v可以将匹配结果进行反转(invert)。
(8) 统计文件或文本中包含匹配字符串的行数:
$ grep -c "text" filename
10
需要注意的是-c只是统计匹配行的数量,并不是匹配的次数。例如:
$ echo -e "1 2 3 4\nhello\n5 6" | egrep -c "[0-9]"
2

尽管有6个匹配项,但命令只打印出2,这是因为只有两个匹配行。在单行中出现的
多次匹配只被统计为一次。
(9) 要文件中统计匹配项的数量,可以使用下面的技巧:
$ echo -e "1 2 3 4\nhello\n5 6" | egrep -o "[0-9]" | wc -l
6
(10) 打印出包含匹配字符串的行号:
$ cat sample1.txt
gnu is not unix
linux is fun
bash is art
$ cat sample2.txt
planetlinux
$ grep linux -n sample1.txt
2:linux is fun
或者
$ cat sample1.txt | grep linux -n
如果涉及多个文件,它也会随着输出结果打印出文件名:
$ grep linux -n sample1.txt sample2.txt
sample1.txt:2:linux is fun
sample2.txt:2:planetlinux
(11) 打印模式匹配所位于的字符或字节偏移:
$ echo gnu is not unix | grep -b -o "not"
7:not
一行中字符串的字符偏移是从该行的第一个字符开始计算,起始值是0。在上面的
例子中,"not"的偏移值是7(也就是说,not是从该行的第7个字符开始的,即“gnu
is not unix”这一行)。
选项 -b总是和 -o配合使用。
(12) 搜索多个文件并找出匹配文本位于哪一个文件中:
$ grep -l linux sample1.txt sample2.txt
sample1.txt
sample2.txt
和-l相反的选项是-L,它会返回一个不匹配的文件列表。

1. 递归搜索文件
如果需要在多级目录中对文本进行递归搜索,可以使用:
$ grep "text" . -R -n
命令中的“.”指定了当前目录。

2. 忽略样式中的大小写
选项 -i可以使匹配样式不考虑字符的大小写,例如:
$ echo hello world | grep -i "HELLO"
hello
3. 用grep匹配多个样式
在进行匹配的时候通常只指定一个样式。然而,我们可以用选项 -e来指定多个匹配样式:
$ grep -e "pattern1" -e "pattern"

我们可以提供一个样式文件用于读取样式。在样式文
件中逐行写下需要匹配的样式,然后用选项 -f执行grep:
$ grep -f pattern_filesource_filename
例如:
$ cat pat_file
hello
cool
$ echo hello this is cool | grep -f pat_file
hello this is cool

有时候,我们并不打算查看匹配的字符串,而只是想知道是否能够成功匹配。这可以通过设
置grep的静默选项(-q)来实现。在静默模式中,grep命令不会输出任何内容。它仅是运行命
令,然后根据命令执行成功与否返回退出状态。
如果命令运行成功会返回0,如果失败则返回非0值。

5. 使用0值字节作为后缀的grep与xargs
xargs命令通常用于将文件名列表作为命令行参数提供给其他命令。当文件名用作命令行参
数时,建议用0值字节作为文件名终止符,而非空格。因为一些文件名中会包含空格字符,一旦
它被误解为终结符,那么单个文件名就会被认为是两个文件名(例如,New file.txt被解析成New
和file.txt两个文件名)。这个问题可以利用0值字节后缀来避免。我们使用xargs以便从诸如grep、
find中接收stdin文本。这些命令可以将带有0值字节后缀的文本输出到stdout。为了指明输入
的文件名是以0值字节(\0)作为终止符,需要在xargs中使用-0。
创建测试文件:
$ echo "test" > file1
$ echo "cool" > file2
$ echo "test" > file3

在下面的命令序列中,grep使用-Z选项输出以0值字节作为终结符的文件名(\0)。xargs -0
读取输入并用0值字节终结符分隔文件名:
$ grep "test" file* -lZ | xargs -0 rm
-Z通常和 -l结合使用。


1 0