本文摘录自 Linux 命令行
操作文本的工具的高级使用需要使用到的技术,是一种符号表示法,是一种文本识别模式。在类 Unix 系统中,文本数据起着举足轻重的作用。但是在我们能完全理解这些工具提供的功能前,我们先来看看与这些工具高级使用关联的技术–正则表达式。
grep:global regular expression print,其中的 regular 作正则的意思。所以我们能看出 grep 和正则有关联。本质上,grep 会在文本文件中查找一个指定的正则表达式,并把匹配行输出到标准输出。
# 我们之前用的查找固定字符串
ls /usr/bin | grep zip
# 创建需要查找的样例
root@bogon Pics # ls /bin > dirlist-bin.txt
root@bogon Pics # ls /usr/bin >dirlist-usr-bin.txt
root@bogon Pics # ls /sbin > dirlist-sbin.txt
root@bogon Pics # ls /usr/sbin > dirlist-usr-sbin.txt
root@bogon Pics # ls dirlist*.txt
dirlist-bin.txt dirlist-usr-bin.txt
dirlist-sbin.txt dirlist-usr-sbin.txt
# 查找含有 bzip 的文件:显示结果显示了文件名+匹配项
root@bogon Pics # grep bzip dirlist*.txt
dirlist-usr-bin.txt:bzip2
dirlist-usr-bin.txt:bzip2recover
# 查找不匹配的文件
root@bogon Pics # grep -L bzip dirlist*.txt
dirlist-bin.txt
dirlist-sbin.txt
dirlist-usr-sbin.txt
# 结果额外显示文本的行号
root@bogon Pics # grep -n bzip dirlist*.txt
dirlist-usr-bin.txt:84:bzip2
dirlist-usr-bin.txt:85:bzip2recover
# 不显示文件名
root@bogon Pics # grep -h bzip dirlist*.txt
bzip2
bzip2recover
选项 | 描述 |
---|---|
-i | 忽略大小写。也可用–ignore-case |
-v | 不匹配。也可用 --invert-match |
-c | 打印匹配的数量(如果指定了 -v 就打印不匹配的数目),而不是文本行本身。也可用 --count |
-l | 打印包含匹配项的文件名,而不是文件行本身。也可用 --files-with-matches |
-n | 在每个匹配行之前打印文件中的相应行号。也可用–line-number |
-h | 应用于多文件搜索,不输出文件名。也可用–no-filename |
-L | 相似于 -l,但是只打印不包含匹配项的文件名。也可用–files-without-match |
看起来不明显,但是 grep 程序一直在使用正则表达式,即使是非常简单的例子。“bzip”这个正则表达式意味着,匹配项所在行至少包含4个字符,顺序固定且中间没有其他字符。字符串“bzip”中的所有字符都是原义字符,它们匹配本身。除了原义字符,正则也可能包含元字符,其被用来指定更复杂的匹配项:^ $ . [] {} - ? * + () | \
,其他字符均为原义字符。如果用反斜杠则可以将元字符转化为原义字符。用引号将元字符引起来则可以阻止 shell 将其展开。
grep -h '.zip' dirlist*.txt
:在文件中查找包含正则“.zip“的文本行。对于搜索结果,我们会发现没有 zip 程序,这是因为圆点符号将它的匹配长度增加到了四个字符。如果有文件是 .zip 也会匹配到。 root@bogon Pics # grep '^zip' dirlist*.txt
dirlist-usr-bin.txt:zip
dirlist-usr-bin.txt:zipcloak
dirlist-usr-bin.txt:zipdetails
dirlist-usr-bin.txt:zipdetails5.18
dirlist-usr-bin.txt:zipdetails5.30
dirlist-usr-bin.txt:zipgrep
dirlist-usr-bin.txt:zipinfo
dirlist-usr-bin.txt:zipnote
dirlist-usr-bin.txt:zipsplit
root@bogon Pics # grep 'zip$' dirlist*.txt
dirlist-usr-bin.txt:funzip
dirlist-usr-bin.txt:gunzip
dirlist-usr-bin.txt:gzip
dirlist-usr-bin.txt:unzip
dirlist-usr-bin.txt:zip
root@bogon Pics # grep '^zip$' dirlist*.txt
dirlist-usr-bin.txt:zip
# 每个 Linux 系统中都有字典,如何在字典中查找包含特定字符且字符位置固定的单词?如查找第三个字母是“j”,第五个字母是“r”的单词
root@bogon Pics # grep -i '^..j.r$' /usr/share/dict/words
Gujar
Kajar
Major
major
grep -h '[bg]zip' dirlist*.txt
:会输出 bzip2、bzip2recover、gizp。一个字符集合可能包含任意多个字符,且元字符被放置到中括号也会失去它们的特殊含义。然而有两个字符在中括号中有着特殊的含义:插入字符^:表示否定;连字符-:表示一个字符范围。 # 如果在中括号表达式中的第一个字符是一个插入符^,则与剩余的字符结合被看作是不会出现的字符集合。得到的文件都有 zip,且 zip 的前一个字符是除了“b”和“g”之外的字符。这里这里也没有出现 zip 程序,因为 ^ 也占了一个字符位置
root@bogon Pics # grep -h '[^bg]zip' dirlist*.txt
bunzip2
funzip`
gunzip
unzip
unzipsfx
# 通过使用三个字符 A-Z,我们就可以表达A到Z的26个字母。下面的用来匹配所有以大写字母开头的文件(注意 ^ 不在中括号中不是否的含义,也不占一个位置)
root@bogon Pics # grep -h '^[A-Z]' dirlist*.txt
AssetCacheLocatorUtil
AssetCacheManagerUtil
AssetCacheTetheratorUtil
DeRez
GetFileInfo
IOAccelMemory
IOMFB_FDR_Loader
...
DirectoryService
KernelEventAgent
PasswordService
WirelessRadioManagerd
# 匹配所有以字母和数字开头的文件
grep -h '^[A-Za-z0-9]' dirlist*.txt
# 上面的 - 连字符被特殊对待,当作展开符号,那怎么样匹配文件中含有 - 的文件呢?只需要将-放在首位就行
grep -h '[-AZ]' dirlist*.txt