如何在Linux/UNIX中使用grep命令

时间:2020-01-09 10:40:49  来源:igfitidea点击:

如何在Linux或Apple macOS/OS X上使用grep命令?
如何在Unix操作系统上使用grep命令?
您能给我一个简单的grep命令示例吗?

grep命令用于搜索文本。
它在给定文件中搜索包含与给定字符串或单词匹配的行。
它是Linux和类Unix系统上最有用的命令之一。
让我们看看如何在类似Linux或Unix的系统上使用grep。

Linux和Unix中的grep命令示例

以下是一些标准grep命令,并通过示例进行了说明,以帮助您开始在Linux,macOS和Unix上使用grep:

  • 在Linux上搜索文件名中包含单词的任何行:`grep'word'filename``
  • 在Linux和Unix中对单词bar执行不区分大小写的搜索:`grep -i'bar'file1``
  • 在Linux的当前目录及其所有子目录中查找所有文件,以查找单词httpd`grep -R'httpd'。''
  • 搜索并显示字符串theitroad在名为frontpage.md的文件中出现的总次数:`grep -c'theitroad'frontpage.md``

让我们详细了解所有命令和选项。

语法

语法如下:

grep 'word' filename
fgrep 'word-to-search' file.txt
grep 'word' file1 file2 file3
grep 'string1 string2'  filename
cat otherfile | grep 'something'
command | grep 'something'
command option1 | grep 'data'
grep --color 'data' fileName
grep [-options] pattern filename
fgrep [-options] words file

如何在Linux上使用grep搜索文件?

在/etc/passwd文件中搜索boo用户,执行:

grep boo /etc/passwd

输出示例:

foo:x:1000:1000:boo,,,:/home/boo:/bin/ksh

我们可以使用fgrep/grep查找文件中包含特定单词的所有行。
例如,要列出当前目录中包含单词California的名为address.txt的文件的所有行,请运行:

fgrep California address.txt

请注意,上面的命令还会返回加利福尼亚(Californication)或加利福尼亚(Californian)等字词的一部分。
因此,在grep/fgrep命令中传递`-w'选项只得到整个单词都包含加利福尼亚的行:

fgrep -w California address.txt

您可以强制grep忽略大小写,即使用-i选项匹配boo,Boo,BOO和所有其他组合。
例如,执行以下命令:

grep -i "boo" /etc/passwd

最后的grep -i" boo"/etc/passwd也可以使用cat命令如下运行:

cat /etc/passwd | grep -i "boo"

如何递归使用grep

您可以进行递归搜索,即读取每个目录下的所有文件以获取字符串192.168.1.5

$ grep -r "192.168.1.5" /etc/

或者

$ grep -R "192.168.1.5" /etc/

输出示例:

/etc/ppp/options:# ms-wins 192.168.1.50
/etc/ppp/options:# ms-wins 192.168.1.51
/etc/NetworkManager/system-connections/Wired connection 1:addresses1=192.168.1.5;24;192.168.1.2;

您将在单独的行上看到192.168.1.5的结果,该结果之前是其中找到文件的文件名(例如/etc/ppp/options)。
可以通过使用-h选项来禁止在输出数据中包含文件名,如下所示:

$ grep -h -R "192.168.1.5" /etc/

或者

$ grep -hR "192.168.1.5" /etc/

输出示例:

# ms-wins 192.168.1.50
# ms-wins 192.168.1.51
addresses1=192.168.1.5;24;192.168.1.2;

如何使用grep仅搜索单词

当您搜索boo时,grep将匹配fooboo,boo123,barfoo35等。
您可以强制grep命令仅选择包含组成整个单词的匹配项的行,即仅匹配boo单词:

$ grep -w "boo" file

如何使用grep搜索2个不同的单词

使用egrep命令,如下所示:

$ egrep -w 'word1|word2' /path/to/file

忽略大小写

我们可以强制grep忽略模式和数据中的区分大小写。
例如,当我搜索bar时,匹配BAR,Bar,BaR等:

$ grep -i 'bar' /path/to/file

在此示例中,我将在搜索中包括所有子目录:

$ grep -r -i 'main' ~/projects/

单词匹配后如何计算行数

grep可以使用-c(count)选项报告每个文件匹配模式的次数:

$ grep -c 'word' /path/to/file

传递-n选项,在输出的每一行之前加上从中获取输出的文本文件中的行号:

$ grep -n 'root' /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
1042:rootdoor:x:0:0:rootdoor:/home/rootdoor:/bin/csh
3319:initrootapp:x:0:0:initrootapp:/home/initroot:/bin/ksh

强制grep反转匹配

您可以使用-v选项来打印反转匹配;也就是说,它仅匹配不包含给定单词的那些行。
例如,打印不包含单词栏的所有行:

$ grep -v bar /path/to/file

$ grep -v '^root' /etc/passwd

在匹配前后显示行

如果要查看匹配开始前的行?
尝试将-B传递给grep:

grep -B NUM "word" file

grep -B 3 "foo" file1

类似地,通过将-A传递给grep来显示匹配后的行:

grep -A NUM "string" /pth/to/file

grep -A 4 "dropped" /var/log/ufw.log

我们可以结合使用这两个选项以获得最有意义的输出:

grep -C 4 -B 5 -A 6 --color 'error-code' /var/log/httpd/access_log

这是获取Linux内核下载URL的示例Shell脚本:

.......
...
_out="/tmp/out.$$"
curl -s https://www.kernel.org/ > "$_out"
#######################
## grep -A used here ##
#######################
url="$(grep -A 2 '<td id="latest_button">' ${_out}  | grep -Eo '(http|https)://[^/"]+.*xz')"
gpgurl="${url/tar.xz/tar.sign}"
notify-send "A new kernel version ($remote) has been released."
echo "* Downloading the Linux kernel (new version) ..."
wget -qc "$url" -O "${dldir}/${file}"
wget -qc "$gpgurl" -O "${dldir}/${gpgurl##*/}"
.....
..

UNIX/Linux管道

grep命令通常与shell管道一起使用。
在此示例中,显示硬盘设备的名称:

# dmesg | egrep '(s|h)d[a-z]'

显示cpu型号名称:

# cat /proc/cpuinfo | grep -i 'Model'

但是,上面的命令也可以在没有shell管道的情况下如下使用:

# grep -i 'Model' /proc/cpuinfo
model		: 30
model name	: Intel(R) Core(TM) i7 CPU       Q 820  @ 1.73GHz
model		: 30
model name	: Intel(R) Core(TM) i7 CPU       Q 820  @ 1.73GHz

我最喜欢的grep或egrep命令用法之一用于过滤yum命令/dpkg命令/apt命令/apt-get命令的输出:

dpkg --list | grep linux-image

yum search php | grep gd

apt search maria | egrep 'server|client'

如何仅列出匹配文件的名称?

使用-l选项列出文件名称,其内容提及main():

$ grep -l 'main' *.c

或者

$ grep -Rl 'main' /path/to/project/dir/

颜色选项

最后,我们可以强制grep以彩色显示输出,执行:

$ grep --color Hyman /etc/passwd

另外,现在默认为红色,我们可以使用GREP_COLOR shell变量定义颜色。
不同的颜色可以帮助我们在视觉上抓地力。

总之,--color选项增加了可读性。
例如,GREP_COLOR环境变量和grep --color = always可以如下使用:

GREP_COLOR='1;35' grep --color=always 'Hyman' /etc/passwd

GREP_COLOR='1;32' grep --color=always 'Hyman' /etc/passwd

GREP_COLOR='1;37' grep --color=always 'root' /etc/passwd

GREP_COLOR='1;36' grep --color=always nobody /etc/passwd

总结

Linux grep命令选项描述
-i忽略Linux和Unix的区分大小写
-w强制模式仅匹配整个单词
-v选择不匹配的线
-n使用输出行打印行号
-h在输出中隐藏Unix文件名前缀
-r在Linux上递归搜索目录
-R就像-r一样,但是遵循所有符号链接
-l仅打印具有选定行的文件名
-c每个文件仅打印选定行的计数
--color以颜色显示匹配的图案