前言: Linux操作中总是会用到查找操作,无论是查找文件、目录,还是查找文件中的内容等。grep命令用于在某个文件文本中查找指定的字符串,类似于word中的ctrl+F,而find命令用于在某个指定的目录中查找某个文件或某个目录。
一、grep
1. grep命令相关参数
用于在某个文件文本中通过正则表达式来查找指定的字符串。当grep被用在shell命令中,正则表达式应该被引号引起来。
grep
即 global regular expression print全局正则表达式打印。
–color=auto 或者 –color:表示对匹配到的文本着色显示
-i:即--ignore-case在搜索的时候忽略大小写
-n:显示结果所在行号
-c:统计匹配到的行数,将不会显示匹配的结果,注意,是匹配到的总行数,不是匹配到的次数,
-o:只显示符合条件的字符串,但是不整行显示,每个符合条件的字符串单独显示一行
-v:输出不带关键字的行(反向查询,反向匹配)
-w:即--word-regexp匹配整个单词,如果是字符串中包含这个单词,则不作匹配。精确搜索
-Cx:即--context=NUM在输出的时候包含结果所在行之前和之后的指定行数,这里指之前和之后的x行,C:context
-e:实现多个选项的匹配,逻辑or关系
-s: 忽略相关不存在或无法读取等错误信息
-E:即--extended-regexp 以扩展的正则表达式进行解析(EREs)
-F:即 --fixed-strings,以固定字符串进行解析
-G:即 --basic-regexp 以基础的正则表达式进行解析,这是默认的
-P:即 --perl-regexp 以兼容perl的正则表达式进行解析
-H: 即 --with-filename 打印每一个匹配的文件名,当多个文件搜索时候这是默认的。
-B: 即显示匹配项的 前num行,before,例如: -B 9 显示匹配行的前9行信息
-A: 即显示匹配项的 后num行,after,例如: -A 9 显示匹配行的后9行信息
2.grep相关例子
grep相关命令格式:
grep [OPTION...] PATTERNS [FILE...]
grep [OPTION...] -e PATTERNS ... [FILE...]
grep [OPTION...] -f PATTERN_FILE ... [FILE...]
例子一:忽略大小写和输出行数
在Helloworld.c文件中搜索main函数,i 代表忽略大小写,n代表输出行号
# grep -in "main" Helloworld.c
3:void main(){
一般默认会以颜色突出关键词,如没有,可以使用 --color
例子二: 输出数量
只想知道有多少行包含指定的字符串,而不在乎哪些行包含这些字符串,使用”-c”选项即可只统计符合条件的总行数,而不会打印出行
例子三:打印上下文
除了打印被搜索到的关键字,还将其上下文打印出来,i 代表忽略大小写,n代表输出行号,C1代表输出其上和其下1行,如果输出2行则为C2
例子四:精确搜索
只精确的关键字进行搜索,而不输出其他相关字符,-w以某个关键字进行精确搜索
第一张图中没有 w,则将 mainhelloworld也输出了,而第二个图中有w选项,则只讲main进行输出。
例子五:反向查询
略,直接填一个参数 v即可
例子六:多个条件,混合查询,“或”的关系
以main和clean进行“或”查询。
例子七:正则匹配
比如: 我想找到当前目录下面的js文件,但是js文件有很多,我需要过滤一下,我所需要的是index开头,以js结尾的文件,那我如何操作呢
ls -alh | grep -E 'in.*\.js$'
这里有一个注意点,千万不能以^in进行搜索,因为grep是按行进行搜索的,而ls -alh的每一行是drwx或-rwx开头的,所以我们无法使用^in去搜索,而单独使用ls命令是可以的,但是ls命令无法显示一些额外的信息比如大小或时间等,例如:
我们找一个其他的目录也一起看下:
例子八:显示相关上下文
-B9 即输出 匹配项的前9行相关信息,before
同理 -A9 即输出匹配项的后9行相关信息,after
例子九:列出当前目录下的 'xxx-1.java'
找出当前目录下面的 x-1.java/ yy-2.java/ zzz-3.java,并对其中后缀的数字进行从小到大排序。
这里涉及到了多个命令的混用,包括 ls / grep / sort , 学习Linux命令行的使用最关键的是多个命令的混用或者说联合使用。
ls | grep -E '.*\-[0-9]+\.java' | sort -t '-' -k 2 -n
解释:
ls 不再赘述
| 不再赘述
grep -E '.*\-[0-9]+\.java' 使用了-E表示后面是扩展的正则表达式,
. 代表任意字符
* 代表 0次或多次
\- 代表转义的-
[0-9] 代表数字的范围即0-9
[0-9]+ 代表数字0-9的个数,即匹配前面数字的次数,1次或多次
\. 代表转义的.
java 扩展名
| 不再赘述
sort 命令
-t '-' 将上述匹配的文件按照'-'进行分隔
-k 2 将上述分隔'-'的两部分,取第二部分
-n 按照数字进行排序
-r 按照逆序进行排序
二、find
用于在目录中搜索文件
1.find命令相关参数
- -exec CMD: .
- -links N : Search for files with ‘N’ links.
- -name demo : Search for files that are specified by ‘demo’.
- -perm octal : Search for the file if permission is ‘octal’.
- -print : Display the path name of the files found by using the rest of the criteria.
- -empty : Search for empty files and directories.
- -size +N/-N : Search for files of ‘N’ blocks; ‘N’ followed by ‘c’can be used to measure the size in characters; ‘+N’ means size > ‘N’ blocks and ‘-N’ means size < ‘N’ blocks.
- -user name : Search for files owned by username or ID ‘name’.
- \(expr \) : True if ‘expr’ is true; used for grouping criteria combined with OR or AND.
-
+n 是大于n , -n 是小于n , n 等于n
-
c
– bytes ,k
– kilobytes ,M
– Megabytes ,G
– Gigabytes
2.find命令相关例子
find . -name sample.txt 查找当前目录下 sample.txt文件
find . -name "*.txt" 查找当前目录下 txt 文件
find . -iname "*.txt" 查找当前目录下txt或TXT文件,忽略大小写
find . -name sample.txt -exec rm -i {} \; 查找sample文件并进行确认删除
find . -empty 查找空的文件或文件夹
find . -type d -empty
find . -type f -empty
find . -perm 664 在当前目录及底层目录中查找 664权限的文件或文件夹
find . -type f -user jack -iname "makefile" | xargs ls -alh
find . -type f -name "abcd" 在当前目录下查找abcd文件
find . -type d -name "mydir" 在当前目录下查找mydir目录
find / -name "*.php" -type f -exec chmod 755 {} \; 在根目录下找php文件并将其改为755
find /etc /home -name "config" -type f 在多个目录下查找config文件,这里是在/home和/etc下查询
find /usr /etc -iname "systemd" -o -iname "gdb" -type f
在/usr和/etc目录下查找 systemd和gdb文件
find / -size 30M 查找大小等于30M的文件
find / -size +2M 查找大小 大于2M的文件
find . -type f -size -10M 查找当前目录下大小 小于10M的文件
find . -type f -size +1M | xargs ls -alh 查找当前目录下大于1M的文件,并列出其详细信息
find . -type f -size +100M -size -200M 查找当前目录下文件大小,大于100M,小于200M的文件
find . -type f -ctime -3 // 在当前目录下查找修改小于3天的文件,ctime修改的是文件的属性、权限、名称位置
find . -type f -mtime -3 // 在当前目录下查找修改小于3天的文件,mtime修改的是文件的内容
find . -type f -mmin -3 // 在当前目录下查找修改小于3分钟的文件
同理还有 cmin,atime, amin等, atime是指 access time通过cat/vim/less/more第一次访问的时间。
find . -name "*.c" -o -name "*.h" //查找当前目录下所有的 .c和.h文件
find . -maxdepth 1 -type f | wc -l // 统计当前目录下的文件数量,不遍历其子目录中文件
三、grep和find混合使用
例子一:查找main函数
先使用find命令,以文件名的方式查找 后缀为.c的文件,然后从这个文件列表中的各个文件依次进行搜索关键字 main,并打印相关关键字所在的行号。
# grep -n main $(find . -name "*.c")
例子二: 查找main函数
先使用find命令搜索当前目录下面的所有文件,然后从这些文件内容中依次查找main
find . | xargs grep --color -nse '\<main\>'
例子三:统计main文件
在当前目录下,查找包含 main 关键字的文件,并输出其相关文件及行数
也就是说,我查找了当前目录下面包含main的所有文件
find ./ -type f -name "*.*" -exec grep -inH --color "main" {} \;
{} 代表是前面输出的文件
; 代表将前面输出的文件进行分隔,而\是对;进行转义,通常;是用于在同一行输入多个命令
+ 表示一次性传递尽可能多的文件路径给后面的命令,这是高效批处理模式:尽可能用单次命令调用处理多个文件, 对比如果用 \;
(分号)结尾,则是每个文件单独执行一次命令
-
using
;
将执行多个命令 (separately for each argument),Example:
$ find /etc/rc* -exec echo Arg: {} \; Arg: /etc/rc.common Arg: /etc/rc.common~previous Arg: /etc/rc.local Arg: /etc/rc.netboot
-
using
+
将执行一次命令,所有查找的内容将会是一行Example:
$ find /etc/rc* -exec echo Arg: {} \+ Arg: /etc/rc.common /etc/rc.common~previous /etc/rc.local /etc/rc.netboot
例子四:统计行数
统计当前目录下, 以.c和.h结尾的文件的行数
find . -name "*.c" -o -name "*.h" | xargs cat | wc -l
例子五:查找前一天修改的所有文件
# 查找前一天修改的所有文件
find . -mtime -1
例子六: 查找所有大小在500k至10M的tar.gz文件
# 查找所有大小在500k至10M的tar.gz文件
find . -size +500k -size -10M -name '*.tar.gz'
例子七: 删除maven/.m2中 关于lastUpdated文件
find . -name *lastUpdated* -type f -print -exec rm -rf {} \;
{} 是占位符,用于表示find所找到的或者匹配的文件
\; 标记命令结束
例子八: 将所找到的jar或pom文件批量上传
find . -type f -not -path '*/\.*' \
-not -path '*/\^archetype-catalog\.xml*' \
-not -path '*/\^maven\-metadata\-local*\.xml*' \
-not -path '*/\^maven\-metadata\-deployment*\.xml*' \
-exec curl -u $USERNAME:$PASSWORD -X PUT -v -T {} $REPO_URL{} \;
例子九: 批量替换脚本中的命名空间
# 基本命令(适用于GNU sed,如Linux发行版)
find /目标路径 -type f -name "*.txt" -exec sed -i 's/old_word/new_word/g' {} +
# 详细说明:
# find /目标路径 :在指定目录递归搜索(默认当前目录用 `.`)
# -type f :只搜索文件
# -name "*.txt" :按通配符匹配文件名(可省略或修改,如 `"*.conf"`)
# -exec ... {} + :对找到的文件执行后续命令
# sed -i :直接修改文件内容(原地替换)
# 's/old_word/new_word/g' :全局替换语法(s表示替换,g表示全局)
{} 是一个替换符号,用于表示前面找到的文件
+ 表示一次性传递尽可能多的文件路径给后面的命令,这是高效批处理模式,尽可能用单次命令调用处理多个文件。 对比如果用 \;(分号)结尾,则是每个文件单独执行一次命令