注意在这两项之间需要使用回车符号。如果没有这个回车符号,搜索就变成了查找一行中的 “STEPHEN BRIAN”。有了这个回车符号之后,它就会查找 “STEPHEN” 的匹配项,以及匹配 “BRIAN” 的项。
还要注意在目标文本两侧必须要放上引号。这样可以将文本与文件名区分开来。
除了在命令行上指定搜索项之外,我们也可以将它们放到一个文件中,并使用这个文件的内容来搜索其他文件。-f 选项让我们可以指定一个包含搜索项的主文件,其中可以列出经常搜索的内容。
举例来说,我们可以想像一个名为 “search_items” 的文件,其中包含了我们希望搜索的两项内容:
# cat search_items
STEPHEN
BRIAN
|
下面的命令在前面的 memo 文件中搜索 “STEPHEN” 和 “BRIAN”:
# fgrep -f search_items memo
3. STEPHEN FLEMING
6. BRIAN LARA
|
egrep 是 grep 的一个功能更加强大的版本,它让我们可以一次搜索多个对象。要搜索的对象是使用回车符(与 fgrep 一样)或管道符(| )来分隔的。
# egrep "STEPHEN
> BRIAN" memo
3. STEPHEN FLEMING
6. BRIAN LARA
# egrep "STEPHEN | BRIAN" memo
3. STEPHEN FLEMING
6. BRIAN LARA
|
上面这两个命令都可以完成相同的工作。
除了搜索多个目标的功能之外,egrep 还提供了重复搜索和分组搜索的功能:
? 查找问号前面字符的零次匹配或一次匹配。
+ 查找加号前面字符的一次或多次匹配。
( ) 表示一个分组。
例如,假设您不记得 Brian 的姓是 “Lara” 还是 “Laras”。
# egrep "LARAS?" memo
6. BRIAN LARA
|
这次搜索会输出同时匹配 “LARA” 和 “LARAS” 的项。下面的搜索稍微有些不同:
# egrep "STEPHEN+" memo
3. STEPHEN FLEMING
|
它可以与 “STEPHEN”、“STEPHENN”、“STEPHENNN” 等匹配。
如果您正在查找一个单词加上它的一个派生词,可以在圆括号中包含派生词的标志字符。
# egrep -i "electron(ic)?s" memo
Sachin Tendulkar, who joins us from XYZ Consumer
Electronics as a national account manager covering
traditional mass merchants.
|
这会查找可以匹配 “electrons” 的项和可以匹配 “electronics” 的项。
总结一下:
+ 号后面的正则表达式可以匹配这个正则表达式的一次或多次出现。
? 号后面的正则表达式可以匹配这个正则表达式的零次或一次出现。
- 使用
| 符号或回车符分隔开的正则表达式会返回可以与任意一个表达式匹配的字符串。
- 正则表达式可以放到圆括号
( ) 中进行分组。
- 我们可以使用的命令行参数包括
-c 、-f 、-i 、-l 、-n 和 -v 。
grep 工具:一个真实的例子
grep 系列工具可以用于任何文本格式的系统文件,以便查找某行中的匹配项。例如,要在 /etc/passwd 文件中查找用户 “root” 的项,可以使用下面的命令:
# grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
|
由于 grep 会查找这个文件中的某个匹配项,因此这个命令会查找到 “root” 和 “operator” 这两项。如果我们希望只查找用户名为 “root” 的项,可以将这个命令修改成下面的样子:
# grep "^root" /etc/passwd
root:x:0:0:root:/root:/bin/bash
|
cut
使用 cut 工具,我们可以将构成文件中数据域的各个列分隔开来。默认的分隔符是制表符,-f 选项可以用来指定希望显示的域。
举例来说,假设一个文本文件 “sample” 有三列,其内容如下所示:
one two three
four five six
seven eight nine
ten eleven twelve
|
现在执行下面的命令:
这会返回:
如果将这个命令修改成:
这会返回下面的不同结果:
one three
four six
seven nine
ten twelve
|
这个命令有几个命令行选项。除了 -f 之外,我们还应该熟悉下面两个选项:
-c —— 允许我们指定字符而不是域。
-d —— 允许我们指定其他分隔符,而不是制表符。
cut:两个实际例子
ls -l 命令可以显示某个目录中所有文件的权限、链接个数、属主、组、大小、日期和文件名 —— 这些都是以空格分隔开的。如果我们对大部分域都不感兴趣,而是只希望了解文件属主的信息,可以使用下面的命令:
# ls -l | cut -d" " -f5
root
562
root
root
root
root
root
root
|
这个命令只会显示文件属主(第 5 个域),而会忽略其他域。
如果您知道文件属主信息开始的第一个字符的确切位置,可以使用 -c 选项来显示文件属主的第一个字符。假设它是从第 16 个字符开始的,下面这个命令就返回第 16 个字符,这是文件属主名的第一个字符。
# ls -l | cut -c16
r
r
r
r
r
r
r
|
如果我们再假设大部分用户都使用最多 8 个字符作为自己的用户名,那么我们就可以使用下面的命令:
这会返回用户名域的那些项。
现在假设文件名是从第 55 个字符开始的,但是我们无法确定文件名会连续占用多少个字符,因为有些文件名可能会比其他文件名长很多。解决方案是从第 55 个字符开始,但却不指定结束字符(这意味着我们要截取该行中所有剩余的内容),如下所示:
# ls -l | cut -c55-
a.out
cscope-15.5
cscope-15.5.tar
cscope.out
memo
search_items
test.c
test.s
|
现在我们来考虑另外一种情况。为了获得系统中所有用户的清单,我们可以从前面使用过的 /etc/passwd 文件中提取第一个域:
# cut -d":" -f1 /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
news
uucp
operator
|
要搜集用户名及其对应的主目录,我们可以提取第 1 个和第 6 个域的内容:
# cut -d":" -f1,6 /etc/passwd
root:/root
bin:/bin
daemon:/sbin
adm:/var/adm
lp:/var/spool/lpd
sync:/sbin
shutdown:/sbin
halt:/sbin
mail:/var/spool/mail
news:/etc/news
uucp:/var/spool/uucp
operator:/root
|
paste 工具可以对文件中的域进行合并。它从每个源文件中提取一行内容,并将其与另外一个源文件中的一行内容合并在一起。
举例来说,假设文件 “fileone” 的内容如下所示:
另外,我们还有一个 “filetwo” 文件,其内容如下所示:
United States
United Kingdom
India
|
下面的命令将这两个文件的内容合并在一起,如下所示:
# paste fileone filetwo
IBM United States
Global United Kingdom
Services India
|
如果 fileone 中的行数比 filetwo 多,那么 paste 操作依然会继续,不过在制表符后面是一些空项。
制表符字符是默认的分隔符,但是我们可以使用 -d 选项将其修改成任何其他值。
# paste -d", " fileone filetwo
IBM, United States
Global, United Kingdom
Services, India
|
我们也可以使用 -s 选项将 fileone 的内容在一行中输出,后面加上一个回车键,然后再显示 filetwo 的内容。
# paste -s fileone filetwo
IBM Global Services
United States United Kingdom India
| |