【shell】用 grep 查找包含字符串的文件|grep 过滤|取匹配行的前后n行

目录

即可即用

grep  匹配多个关键字

与find的不同

grep检索文件内容详解

grep指定搜索的文件类型

grep  不起作用?过滤了还是显示

匹配特定的列

指定在哪些文件/哪类文件/哪个目录里搜索

 搜索时包含/排除哪类文件

搜索时排除指定目录

指定在哪些文件里搜索(匹配文件名)

更多过滤

搜索包含[指定字符串]的文件

搜索包含[特定单词]的文件

显示包含[特定文本]的文件

大小写不敏感的搜索

显示包含搜索字符串的行号

寻找不包含[指定字符串]的文件

只取第一行、取前n行、取前n字节、取末尾n行、不显示前n行/后n行

取匹配命中的前后n行

精确过滤

显示文件名和隐藏文件名

正则表达式

压缩文件内容搜索


本文随时更新,原文地址:http://t.csdn.cn/meOqn

即可即用

grep  匹配多个关键字


1、 grep ‘字符串’

cat manpath.config | grep 'MANPATH'


2、 反向匹配(not)

cat manpath.config| grep -v 'MANPATH'


3、 匹配多个关键字之一(or)

grep -E "word1|word2|word3" file.txt

egrep "word1|word2|word3" file.txt

grep -e word1 -e word2 -e word3 file.txt


4、 反向匹配多个关键字之一(not)

grep -vE "word1|word2|word3" file.txt

5、同时满足多个关键字(and)

grep word1 file.txt | grep word2 |grep word3

如果只and两个,可以

grep -E  ‘word1 .*word2 ’  file.txt  #表匹配……word1……word2……的字符串,”.* ”表示任意字符串
grep -E ‘word1 .*word2|word2 .*word1’  file.txt“ #表匹配……word1……word2……或……word2……word1……的字符串,”.* ”表示任意字符串

与find的不同

find命令是根据文件的属性进行查找,如文件名,文件大小,所有者,所属组,是否为空,访问时间,修改时间等。 

 grep是根据文件的内容进行查找,会对文件的每一行按照给定的模式(patter)进行匹配查找。

grep检索文件内容详解

https://www.jb51.net/article/127783.htm

grep指定搜索的文件类型

(1) 指定文件类型
find -type f -name '*.h' | xargs grep "hello"


(2) 指定or排除java和c文件类型

grep "hello" -nR --include=*.{java,c}

grep "hello" -nR --exclude=*.{java,c}

(3) 排除lib目录查找文件init.c

find -name lib -prune -o -name init.c

原文链接:https://blog.csdn.net/wenwang88/article/details/79254337

(4)grep 转义字符“\” 查找

grep 转义字符“\” 查找_chengf223的博客-CSDN博客_grep转义字符

(5)非递归搜索

grep -s "stretch "/etc/*

-s 选项会在发现不存在或者不能读取的文件时隐藏报错信息。

(5)递归搜索

grep -R "stretch "/etc/*

grep -rEn perl /usr/bin/
grep -Rl "3306" * 这句可以显示在哪个文件里包含3306
grep -REn "3306" * 可以显现文件名,行数
R 表示递归,就是在当前目录找不到就去子目录找
E 表示把文件名也打印出来
n 打印此行在文件中的位置

(6)显示行号

grep -Rni bash /etc/*.conf

使用 grep 查找所有包含指定文本的文件 | 《Linux就该这么学》

grep  不起作用?过滤了还是显示

service --status-all | grep network,即使我将其通过管道传送到grep以仅将其限制为”network”字符串,它仍然列出所有服务

解决办法:

service --status-all |& grep network

services - 为什么此grep命令不起作用? - Ubuntu问答

Stdout的编号为1,stderr的编号为2。默认情况下,重定向操作符(如>|<)仅适用于stdout的编号1。

|&将stdout和stderr一起输送到右侧标准输入(stdin)流上的进程,这使grep可以按预期工作。

匹配特定的列

先用awk对特定列过滤,然后再用grep

$ awk '$2 == 866' test.txt

指定在哪些文件/哪类文件/哪个目录里搜索

 搜索时包含/排除哪类文件

grep 命令也可以只在指定文件中进行搜索。比如,我们可以只在配置文件(扩展名为.conf)中搜索指定的文本/字符串。 下面这个例子就会在 /etc 目录中搜索带字符串 bash 且所有扩展名为 .conf 的文件:

只在txt的文件内搜hello  (单个类型)

# grep -nR  “hello”  --include=*.txt

只在.txt\.sh的文件内搜hello (多个类型)

# grep -nR  “hello”  --include=*.{txt,sh}

# grep -Ril bash /etc/*.conf
OR
# grep -Ril --include=\*.conf bash /etc/*
/etc/adduser.conf

类似的,也可以使用 --exclude 来排除特定的文件:

# grep -Ril --exclude=\*.conf bash /etc/*
/etc/alternatives/view
/etc/alternatives/vim
/etc/alternatives/vi
/etc/alternatives/vimdiff
/etc/alternatives/rvim
/etc/alternatives/ex
/etc/alternatives/rview
/etc/bash.bashrc
/etc/bash_completion.d/grub
/etc/cron.daily/apt-compat
/etc/cron.daily/exim4-base
/etc/dictionaries-common/default.hash
/etc/dictionaries-common/words
/etc/inputrc
/etc/passwd
/etc/passwd-
/etc/profile
/etc/shells
/etc/skel/.profile
/etc/skel/.bashrc
/etc/skel/.bash_logout

搜索时排除指定目录

跟文件一样,grep 也能在搜索时排除指定目录。 使用 --exclude-dir 选项就行。

下面这个例子会搜索 /etc 目录中搜有包含字符串 stretch 的文件,但不包括 /etc/grub.d 目录下的文件:

# grep --exclude-dir=/etc/grub.d -Rwl stretch /etc/*
/etc/apt/sources.list
/etc/dictionaries-common/words
/etc/os-release

指定在哪些文件里搜索(匹配文件名)

find在/root目录下搜索名为tom_renam的文件,在搜出的tom_renam文件中搜索“hello”

find    /root     -name   tom_renam    -exec grep -nR  "hello" {} \;

-exec command:command ,-exec 后面接其他执行的指令来处理搜寻到的结果。

{ } 代表的是「由 find 找到的内容」找到的结果会被放置到 { } 位置中;
-exec  到 ; 代表处理搜寻到的结果的动作,因为「;」在bash的环境下是有特殊意义的,要在前面加反斜杠\转译。

ls 当前目录,对文件名含“dse.engine”字符串的进行查找

ls |grep "dse.engine"| xargs -I {}  grep -nR "ms_dispatch"  {}

更多过滤

约定:

  • # - 需要使用 root 权限来执行指定命令,可以直接使用 root 用户来执行也可以使用 sudo 命令
  • $ - 可以使用普通用户来执行指定命令

案例

搜索包含[指定字符串]的文件

非递归

第一个例子让我们来搜索 /etc/ 目录下所有包含 stretch 字符串的文件,但不去搜索其中的子目录:

# grep -s stretch /etc/*
/etc/os-release:PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
/etc/os-release:VERSION="9 (stretch)"

grep 的 -s 选项会在发现不存在或者不能读取的文件时隐藏报错信息。结果显示除了文件名之外,还有包含请求字符串的行也被一起输出了。

递归

上面案例中忽略了所有的子目录。所谓递归搜索就是指同时搜索所有的子目录。

下面的命令会在 /etc/ 及其子目录中搜索包含 stretch 字符串的文件:

# grep -R stretch /etc/*
/etc/apt/sources.list:# deb cdrom:[Debian GNU/Linux testing _Stretch_ - Official Snapshot amd64 NETINST Binary-1 20170109-05:56]/ stretch main
/etc/apt/sources.list:#deb cdrom:[Debian GNU/Linux testing _Stretch_ - Official Snapshot amd64 NETINST Binary-1 20170109-05:56]/ stretch main
/etc/apt/sources.list:deb http://ftp.au.debian.org/debian/ stretch main
/etc/apt/sources.list:deb-src http://ftp.au.debian.org/debian/ stretch main
/etc/apt/sources.list:deb http://security.debian.org/debian-security stretch/updates main
/etc/apt/sources.list:deb-src http://security.debian.org/debian-security stretch/updates main
/etc/dictionaries-common/words:backstretch
/etc/dictionaries-common/words:backstretch's
/etc/dictionaries-common/words:backstretches
/etc/dictionaries-common/words:homestretch
/etc/dictionaries-common/words:homestretch's
/etc/dictionaries-common/words:homestretches
/etc/dictionaries-common/words:outstretch
/etc/dictionaries-common/words:outstretched
/etc/dictionaries-common/words:outstretches
/etc/dictionaries-common/words:outstretching
/etc/dictionaries-common/words:stretch
/etc/dictionaries-common/words:stretch's
/etc/dictionaries-common/words:stretched
/etc/dictionaries-common/words:stretcher
/etc/dictionaries-common/words:stretcher's
/etc/dictionaries-common/words:stretchers
/etc/dictionaries-common/words:stretches
/etc/dictionaries-common/words:stretchier
/etc/dictionaries-common/words:stretchiest
/etc/dictionaries-common/words:stretching
/etc/dictionaries-common/words:stretchy
/etc/grub.d/00_header:background_image -m stretch `make_system_path_relative_to_its_root "$GRUB_BACKGROUND"`
/etc/os-release:PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
/etc/os-release:VERSION="9 (stretch)"

搜索包含[特定单词]的文件

上面 grep 命令的案例中列出的是所有包含字符串 stretch 的文件。也就是说包含 stretches , stretched 等内容的行也会被显示。 使用 grep 的 -w 选项会只显示包含特定单词的行:

# grep -Rw stretch /etc/*
/etc/apt/sources.list:# deb cdrom:[Debian GNU/Linux testing _Stretch_ - Official Snapshot amd64 NETINST Binary-1 20170109-05:56]/ stretch main
/etc/apt/sources.list:#deb cdrom:[Debian GNU/Linux testing _Stretch_ - Official Snapshot amd64 NETINST Binary-1 20170109-05:56]/ stretch main
/etc/apt/sources.list:deb http://ftp.au.debian.org/debian/ stretch main
/etc/apt/sources.list:deb-src http://ftp.au.debian.org/debian/ stretch main
/etc/apt/sources.list:deb http://security.debian.org/debian-security stretch/updates main
/etc/apt/sources.list:deb-src http://security.debian.org/debian-security stretch/updates main
/etc/dictionaries-common/words:stretch
/etc/dictionaries-common/words:stretch's
/etc/grub.d/00_header:background_image -m stretch `make_system_path_relative_to_its_root "$GRUB_BACKGROUND"`
/etc/os-release:PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
/etc/os-release:VERSION="9 (stretch)"

显示包含[特定文本]的文件

上面的命令都会产生多余的输出。下一个案例则会递归地搜索 etc 目录中包含 stretch 的文件并只输出文件名:

# grep -Rl stretch /etc/*
/etc/apt/sources.list
/etc/dictionaries-common/words
/etc/grub.d/00_header
/etc/os-release

大小写不敏感的搜索

默认情况下搜索是大小写敏感的,也就是说当搜索字符串 stretch 时只会包含大小写一致内容的文件。

通过使用 grep 的 -i 选项,grep 命令还会列出所有包含 Stretch , STRETCH , StReTcH 等内容的文件,也就是说进行的是大小写不敏感的搜索。

# grep -Ril stretch /etc/*
/etc/apt/sources.list
/etc/dictionaries-common/default.hash
/etc/dictionaries-common/words
/etc/grub.d/00_header
/etc/os-release

显示包含搜索字符串的行号

-n 选项还会显示指定字符串所在行的行号:

# grep -Rni bash /etc/*.conf
/etc/adduser.conf:6:DSHELL=/bin/bash

寻找不包含[指定字符串]的文件

最后这个例子使用 -v 来列出所有包含指定字符串的文件。

例如下面命令会搜索 /etc 目录中不包含 stretch 的所有文件:

# grep -Rlv stretch /etc/*

via: https://linuxconfig.org/how-to-find-all-files-with-a-specific-text-using-linux-shell

只取第一行、取前n行、取前n字节、取末尾n行、不显示前n行/后n行

(head命令与tail命令)

#显示前5个字节

head -c 5 head.txt

# 只显示前五行
head -n 5 test.txt
# 只显示末尾五行
tail -n 5 test.txt
# 只显示第三行到末尾(不显示前两行)
tail -n +3 test.txt
# 只显示开头到末尾第三行(不显示末尾两行)
head -n -3 test.txt
# 只显示开头第三行到末尾第三行(不显示前两行且不显示末尾两行)
tail -n +3 test.txt | head -n -3

只取第一行

grep *.*|head -n 1

只取前n行

#显示前5行

head -n  5 head.tx

只取前n字节

head 【参数】【文件】

2、命令选项

-c, --bytes=[-]K   k,显示文档开始的前k个字节,-k,不显示文档结尾的最后 k 个字节

-n, --lines=[-]K    k,显示文档开始的前k行,-k,不显示文档结尾的最后 k 行

-q, --quiet, --silent    不显示包含给定文件名的文件头

-v, --verbose      总是显示包含给定文件名的文件头

--help        显示此帮助信息并退出

--version      显示版本信息并退出

取匹配命中的前后n行

$grep -5 'parttern' inputfile //打印匹配行的前后5行

$grep -C 5 'parttern' inputfile //打印匹配行的前后5行

$grep -A 5 'parttern' inputfile //打印匹配行的后5行

$grep -B 5 'parttern' inputfile //打印匹配行的前5行

grep -A  -B -C(大写)    后面都跟阿拉伯数字 
-A是显示匹配后和它后面的n行。after 
-B是显示匹配行和它前面的n行。 before
-C是匹配行和它前后各n行。 context

例如:grep -A 1 hello test.txt 
就是搜索test.txt,找到匹配“hello”字串的行,显示该行和后面的1行。
例如:grep -B 1 hello test.txt 
就是搜索test.txt,找到匹配“hello”字串的行,显示该行和前面的1行。
例如:grep -C 1 hello test.txt 
就是搜索test.txt,找到匹配“hello”字串的行,显示该行和前后1行。

精确过滤

grep的-o选项

...
<input type="hidden" name="fd" value="Q2m4nLJN4aGSAYmtrsIZAw6vnQRy" />
<input type="hidden" name="execution" value="e1s1" />
<input type="hidden" name="_eventId" value="submit" />
...

表达式:

[root@localhost grep-o]# cat page.html  | grep 'name="execution" value="[a-zA-Z0-9-]\+".*>'

<input type="hidden" name="execution" value="e1s1" />

显示文件名和隐藏文件名

grep -H "foo" file      结果显示文件名

grep -h "foo" file    结果不显示文件名


正则表达式

linux grep 正则表达式

grep正则表达式元字符集:

 ^ 锚定行的开始 如:'^grep'匹配所有以grep开头的行。

$ 锚定行的结束 如:'grep$'匹配所有以grep结尾的行。

. 匹配一个非换行符的字符 如:'gr.p'匹配gr后接一个任意字符,然后是p。

* 匹配零个或多个先前字符 如:'*grep'匹配所有一个或多个空格后紧跟grep的行。 .*一起用代表任意字符。

 [] 匹配一个指定范围内的字符,如'[Gg]rep'匹配Grep和grep。

[^] 匹配一个不在指定范围内的字符,如:'[^A-FH-Z]rep'匹配不包含A-R和T-Z的一个字母开头,紧跟rep的行。

.... 标记匹配字符,如'lovelove',love被标记为1。

\ 锚定单词的开始,如:'\匹配包含以grep开头的单词的行。

\> 锚定单词的结束,如'grep\>'匹配包含以grep结尾的单词的行。

x\{m\} 重复字符x,m次,如:'0\{5\}'匹配包含5个o的行。

x\{m,\} 重复字符x,至少m次,如:'o\{5,\}'匹配至少有5个o的行。

x\{m,n\}重复字符x,至少m次,不多于n次,如:'o\{5,10\}'匹配5--10个o的行。

 \w 匹配文字和数字字符,也就是[A-Za-z0-9],如:'G\w*p'匹配以G后跟零个或多个文字或数字字符,然后是p。

 \b 单词锁定符,如: '\bgrep\b'只匹配grep。

以什么开头+以什么结尾

以“f”开头并以.frm结尾正则表达式 :

   "f[[:alnum:]]*\.frm"

 常用的 grep 选项有:

 -c 只输出匹配行的个数。
 -i 不区分大小写(只适用于单字符)。
 -h 查询多文件时不显示文件名。
 -l 查询多文件时只输出包含匹配字符的文件名。
 -n 显示匹配行及行号。
 -s 不显示不存在或无匹配文本的错误信息。
 -v 显示不包含匹配文本的所有行。
 -V 显示软件版本信息

 使用grep匹配时最好用双引号引起来,防止被系统误认为参数或者特殊命令,也可以匹配多个单词。

 关于匹配的实例:

 grep -c "48" test.txt 统计所有以“48”字符开头的行有多少

grep -i "May" test.txt 不区分大小写查找“May”所有的行)

 grep -n "48" test.txt 显示行号;显示匹配字符“48”的行及行号,相同于 nl test.txt |grep 48)

 grep -v "48" test.txt 显示输出没有字符“48”所有的行)

 grep "471" test.txt 显示输出字符“471”所在的行)

 grep "48;" test.txt 显示输出以字符“48”开头,并在字符“48”后是一个tab键所在的行

 grep "48[34]" test.txt 显示输出以字符“48”开头,第三个字符是“3”或是“4”的所有的行)

 grep "^[^48]" test.txt 显示输出行首不是字符“48”的行)

 grep "[Mm]ay" test.txt 设置大小写查找:显示输出第一个字符以“M”或“m”开头,以字符“ay”结束的行)

 grep "K…D" test.txt 显示输出第一个字符是“K”,第二、三、四是任意字符,第五个字符是“D”所在的行)

 grep "[A-Z][9]D" test.txt 显示输出第一个字符的范围是“A-D”,第二个字符是“9”,第三个字符的是“D”的所有的行

 grep "[35]..1998" test.txt 显示第一个字符是3或5,第二三个字符是任意,以1998结尾的所有行

 grep "4\{2,\}" test.txt 模式出现几率查找:显示输出字符“4”至少重复出现两次的所有行

 grep "9\{3,\}" test.txt 模式出现几率查找:显示输出字符“9”至少重复出现三次的所有行

 grep "9\{2,3\}" test.txt 模式出现几率查找:显示输出字符“9”重复出现的次数在一定范围内,重复出现2次或3次所有行

 grep -n "^$" test.txt 显示输出空行的行号

 ls -l |grep "^d" 如果要查询目录列表中的目录 同:ls -d *

 ls -l |grep "^d[d]" 在一个目录中查询不包含目录的所有文件

 ls -l |grpe "^d…..x..x" 查询其他用户和用户组成员有可执行权限的目录集合

压缩文件内容搜索

gzip -dc ./文件名.gz | grep “8723183”
gzip -dc ./*.gz | grep “8723183”

还可以用zgrep命令

zgrep -rin “8723183” ./文件名.gz

posted on 2022-10-04 01:24  bdy  阅读(1012)  评论(0编辑  收藏  举报

导航