Linux which whereis locate grep find
概览
which : 查看执行文件的位置。
whereis : 查看可执行文件位置和相关文件。
locate : 配合数据库缓存,快速查看文件的位置。
grep : 过滤匹配,他是一个文件搜索工具。
find : 可以根据条件查看文件。
which
在 PATH 变量中定义的全部路径中查找可执行文件或脚本。which
命令有两个重要参数:
-all, -a
默认情况下,which
命令会在匹配到第一个结果后结束运行,添加该参数可以让其搜索所有路径。-read-alias, -i
将输入视为别名搜索。Linux 系统中通常会使用 alias 设置诸多别名来简写命令,例如 Centos 中的ll
实际是ls -l
,而which
是alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde
。# Centos # 以绝对路径调用 which,这样就不会受到 Centos 默认的几个参数影响 # 返回结果说明找不到 ll 命令 $ /usr/bin/which ll /usr/bin/which: no ll in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin) # 直接输入 which 时实际效果为带有“默认参数”的 # 返回结果说明 ll 是 ls -l 的别名, $ which ll alias ll='ls -l --color=auto' /usr/bin/ls
which ll
相当于alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde ll
,返回结果第一行是 alias 输出的ll
别名设置情况,第二行则是ls
的实际位置。
which
的其他几个参数如下:
--tty-only
:尽在终端调用的情况下附带右侧添加的参数,其他情况下不接收右侧其他参数(此处的参数值--show-dot
、--show-tilde
此类,输入的待查询命令仍然会接收),通过这个命令可以保证 Shell 脚本中的which
命令正确执行。--show-dot
:输出以 “.” 符号开头的目录。Linux 中 “.
“ 符号开头的目录是约定的隐藏文件夹,没有该参数时会忽略这些目录。--show-tilde
:将用户家目录替换成 “~” 符号输出。Linux 中 “~
“ 符号是登录用户家目录的缩写,如果登录用户名为 cncsl,则 “~” 指 “/home/cncsl” 目录。当使用 root 账号登录时该参数无效。--all, -a 显示所有的匹配路径
操作:➜ / which pwd /usr/bin/pwd
whereis
查找指定命令的可执行文件、源代码和手册的位置。
$ whereis vim vim: /usr/bin/vim /usr/share/vim /usr/share/man/man1/vim.1.gz
可以看出,
vim
的可执行程序位于/usr/bin/vim
,手册位于/usr/share/vim
和/share/man/man1/vim.1.gz
目录。-b
、-m
和-s
分别用于指定仅查询可执行文件、手册和源代码。-B
、-M
和-S
命令用于指定查询路径。-u
参数的描述直译为仅查询有异常情况的命令。所谓的异常情况是指,某个命令的相关类型文件不止恰好一份(一份都没有或多于一份)。例如:ls
命令具有两份手册:$ whereis -m -u ls ls: /usr/share/man/man1/ls.1.gz /usr/share/man/man1p/ls.1p.gz
Linux 系统中有很多个与 python 相关的可执行文件:
$ whereis -b -u python python: /usr/bin/python /usr/bin/python2.7 /usr/lib/python2.7 /usr/lib64/python
一般不加参数使用
-b 只搜索二进制文件
-B <目录> 定义二进制文件查找路径
-m 只搜索 man 手册
-M <目录> 定义 man 手册查找路径
-s 只搜索源代码
-S <目录> 定义源代码查找路径
操作:
➜ / whereis ls
ls: /usr/bin/ls /usr/share/man/man1/ls.1.gz
locate
在文档和目录名称的数据库中查找指定文件。
Linux 系统会定期自动扫描磁盘来维护一个记录磁盘数据的数据库,而 locate
命令使用的数据库是 /var/lib/mlocate/mlocate.db。
$ ls -hl /var/lib/mlocate/mlocate.db
-rw-r-----. 1 root slocate 2.7M Feb 4 03:42 /var/lib/mlocate/mlocate.db
可以看出当前 mlocate.db 文件共记录了 2.7M 的数据。
--count, -c
:不输出具体的文件路径信息,仅输出查询到的数量。--ignore-case, -i
:查询时忽略大小写--limit, -l, -n LIMIT
:限定输出的文件数量为 LIMIT--regexp,-r REGEXP
:使用 REGEXP 指定的正则表达式匹配。# 统计有多少PNG格式的图像文件 $ locate -c png # 统计有多少 readme 文件(根据编写者的习惯,readme 文件可能名为 README、ReadMe等) $ locate -c -i readme # 输出十个 .gz 归档文件的路径 $ locate -l 10 *.gz # 查看 tomcat 2021年1月的日志 $ locate -r tomcat.2021-01-[0-3][0-9].log
由于
locate
命令是从数据库查找文件,新创建的文件可能由于未被记录到数据库中而无法查询到,这种时候需要使用updatedb
命令手动更新数据库。
操作: locate和find命令功能差不多,但是搜索效率更高,因为locate查的是数据库而find查找的是目录文件。
数据库:➜ ~ ls /var/lib/mlocate/mlocate.db /var/lib/mlocate/mlocate.db
相关配置文件:
➜ ~ ls /etc/updatedb.conf /etc/updatedb.conf
相关定时任务:
➜ ~ ls /etc/cron.daily/mlocate /etc/cron.daily/mlocate
举例:
➜ ~ touch shafa ➜ ~ locate shafa ➜ ~ updatedb ➜ ~ locate shafa /root/shafa
:::tips 注:如果当天新建的文件查找,需要手动updatedb。 :::
grep
命令:grep
语法:grep 参数 目标值 文件
与 grep 相似的工具还有egrep
、fgrep
,实用性并不强,其功能完全可以通过 grep 的扩展参数来实现。常用参数
-A
:除了匹配行,额外显示该行之后的N行-B
:除了匹配行,额外显示该行之前的N行-C
:除了匹配行,额外显示该行前后的N行-c
:统计匹配的行数-e
:实现多个选项间的逻辑 or 关系-E
:支持扩展的正则表达式-F
:相当于 fgrep-i
:忽略大小写-n
:显示匹配的行号-o
:仅显示匹配到的字符串-q
:安静模式,不输出任何信息,脚本中常用-s
:不显示错误信息-v
:显示不被匹配到的行-w
:显示整个单词--color
:以颜色突出显示匹配到的字符串-v 取反 -i 忽略大小写 -n 输出的同时打印行号 ^* 以*开头 *$ 以*结尾 ^$ 空行
操作
查 /etc/passwd有root的行
➜ / grep root /etc/passwd root:x:0:0:root:/root:/bin/zsh operator:x:11:0:operator:/root:/sbin/nologin dockerroot:x:996:993:Docker User:/var/lib/docker:/sbin/nologin
查 /etc/passwd 没有root的行(内容较多,仅展示几行)
➜ / grep -v root /etc/passwd bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin systemd-bus-proxy:x:999:998:systemd Bus Proxy:/:/sbin/nologin systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin polkitd:x:998:997:User for polkitd:/:/sbin/nologin tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin chrony:x:997:995::/var/lib/chrony:/sbin/nologin ntp:x:38:38::/etc/ntp:/sbin/nologin nscd:x:28:28:NSCD Daemon:/:/sbin/nologin tcpdump:x:72:72::/:/sbin/nologin mysql:x:995:1000::/home/mysql:/bin/bash
查 /etc/passwd 有root的行并显示行号
➜ / grep -n root /etc/passwd 1:root:x:0:0:root:/root:/bin/zsh 10:operator:x:11:0:operator:/root:/sbin/nologin 25:dockerroot:x:996:993:Docker User:/var/lib/docker:/sbin/nologin
grep forest f.txt #文件查找 grep forest f.txt cpf.txt #多文件查找 grep 'log' /home/admin -r -n #目录下查找所有符合关键字的文件 cat f.txt | grep -i shopbase grep 'shopbase' /home/admin -r -n --include *.{vm,java} #指定文件后缀 grep 'shopbase' /home/admin -r -n --exclude *.{vm,java} #反匹配 seq 10 | grep 5 -A 3 #上匹配 seq 10 | grep 5 -B 3 #下匹配 seq 10 | grep 5 -C 3 #上下匹配,平时用这个就妥了 cat f.txt | grep -c 'SHOPBASE'
把包含 syslog 的行过滤出来
```bash $ grep “syslog” g.txt syslog:x:104:108::/home/syslog:/bin/false
可以忽略大小写
$ grep -i “SYSLOG” g.txt syslog:x:104:108::/home/syslog:/bin/false
<a name="ZylIv"></a>
#### 把以 ntp 开头的行过滤出来
```bash
$ grep "^ntp" g.txt
ntp:x:108:114::/home/ntp:/bin/false
# 把false结尾的行过滤出来
$ grep "false$" g.txt
syslog:x:104:108::ntp.syslog:/bin/false
ntp:x:108:114::/home/ntp:/bin/false
把匹配 ntp 的行以及下边的两行过滤出来
$ grep -A2 "syslog" g.txt
syslog:x:104:108::ntp.syslog:/bin/false
ntp:x:108:114::/home/ntp:/bin/false
sshd:x:109:65534::sshd:/usr/sbin/nologin
把包含 syslog 及上边的一行过滤出来
$ grep -B1 "syslog" g.txt
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
syslog:x:104:108::ntp.syslog:/bin/false
把包含 syslog 以及上、下一行内容过滤出来
$ grep -C1 "syslog" g.txt
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
syslog:x:104:108::ntp.syslog:/bin/false
ntp:x:108:114::/home/ntp:/bin/false
过滤某个关键词,并输出行号
$ grep -n "ntp" g.txt
3:syslog:x:104:108::ntp.syslog:/bin/false
4:ntp:x:108:114::/home/ntp:/bin/false
过滤不包含某关键词,并输出行号
$ grep -n -v "sbin" g.txt
1:0root:x:0:0:root:/root:/bin/zsh
3:syslog:x:104:108::ntp.syslog:/fnlas
4:ntp:x:108:114::/home/ntp:/bin/false
删除掉空行
$ grep -v "^$" g.txt
# "^$"表示空行
过滤包含 root 或 syslog 的行
# 用"-e"实现多选项间逻辑or关系
$ grep -e "root" -e "syslog" g.txt
0root:x:0:0:root:/root:/bin/zsh
syslog:x:104:108::ntp.syslog:/bin/false
# 等效于
$ grep -E "root|syslog" g.txt
查看当前目录中包含某关键词的所有文件(这个很有用)
# -r 表示在当前目录递归查询
$ grep -r "font" .
./README.md: --pdf-mono-font-size 12
./default.css: font-size: 120%;
./default.css: font-weight: bold;
./ samples/foo/genmobi.sh: --default-font 12
# 一般会用下边的命令,会更加有效(显示行号,且以单词严格匹配)
$ grep -rnw "font" .
# 在递归的过程中排除某些目录
$ grep -rnw --exclude-dir={.git,svn} "mail"
grep命令的其他操作
grep -H 'spring' *.xml
查找所以有的包含spring的xml文件grep 'test' d*
显示所有以d开头的文件中包含test的行。grep 'test' aa bb cc
显示在aa,bb,cc文件中匹配test的行。grep '[a-z]\{5\}' aa
显示所有包含每个字符串至少有5个连续小写字符的字符串的行。
find
在一个目录层级中查找文件。find
命令功能强大,可根据多种条件查询文件,随后进行自定义的操作,格式如下:
find [path...] [expression]
find
会实际的扫描磁盘,所以速度会明显小于前三个。
命令:find
语法:find 路径 参数 输出
查找路径:指定具体目标路径;默认为当前目录
查找条件:指定的查找标准,可以文件名、大小、类型、权限等标准进行;默认找出指定路径下的所有文件
处理动作:对符合条件的文件做操作,默认输出至屏幕
查找条件
指搜索层级
-maxdepth level 最大搜索目录深度,指定目录为第1级
-mindepth level 最小搜索目录深度
先处理目录内的文件,再处理目录
根据文件名和inode查找
-name“文件名称”:支持使用glob
*,?,[],[^]
-iname“文件名称”:不区分字母大小写
-inum n 按inode号查找
-samefile name 相同inode号的文件
-links n 链接数为n的文件
-regex “PATTERN”:以PATTERN匹配整个文件路径,而非文件名称
根据属主、属组查找
-user USERNAME:查找属主为指定用户(UID)的文件
-group GRPNAME:查找属组为指定组(GID)的文件
-uid UserID:查找属主为指定的UID号文件
-gid GroupID:查找属组为指定的GID号的文件
-nouser:查找没有属主的文件
-nogroup:查找没有属组的文件
根据文件类型查找
type TYPE:
f:普通文件
d:目录文件
l:符号链接文件
s:套接字文件
b:块设备文件
c:字符设备文件
p:管道文件
空文件或目录
组合条件
常用参数
路径: 例如用 . 来表示当前目录,用 / 来表示系统根目录。
-print:显示的时候”\n”做为定界符, 换行
-print0:与xargs配套使用,以“\0”做为定界符
find常用命令选项:
-name 按照文件名查找文件。“名称”
-perm 按照文件权限来查找文件。666 777 等
-depth 在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找
-user 按照文件属主来查找文件
-atime -ctime (单位是天)
-mmin -cmin -amin(单位是分钟)
-size n [c] 查找文件长度为n块的文件,带有c时表示文件长度以字节计
-follow 如果find命令遇到符号链接文件,就跟踪至链接所指向的文件。
操作
根据文件名称查找
find / -name filename.txt
根据名称查找/目录下的filename.txt文件。find . -name "*.xml"
递归查找所有的xml文件
查看当前目录下文件名为.conf的文件
➜ /etc find *.conf
asound.conf
chrony.conf
dnsmasq.conf
dracut.conf
e2fsck.conf
GeoIP.conf
查看当前目录下yum.开头的文件,输出结果换行显示(默认)
➜ /etc find yum.* -print
yum.conf
yum.repos.d
yum.repos.d/CentOS-Base.repo
yum.repos.d/epel.repo
➜ /etc find yum.*
yum.conf
yum.repos.d
yum.repos.d/CentOS-Base.repo
yum.repos.d/epel.repo
查看当前目录下yum.开头的文件,输出结果不换行显示
➜ /etc find yum.* -print
yum.conf
yum.repos.d
yum.repos.d/CentOS-Base.repo
yum.repos.d/epel.repo
➜ /etc find yum.*
yum.conf
yum.repos.d
yum.repos.d/CentOS-Base.repo
yum.repos.d/epel.repo
➜ /etc find yum.* -print0
yum.confyum.repos.dyum.repos.d/CentOS-Base.repoyum.repos.d/epel.repo#
对查找的内容执行相应命令
默认执行动作 : -print
常用动作:
-exec 这个参数后可以跟自定义shell命令
查询yum.开头的文件并用ls查询其更多属性
➜ /etc find yum.* -exec ls -l {} \;
-rw-r--r--. 1 root root 970 Nov 15 2016 yum.conf
total 8
-rw-r--r-- 1 root root 675 Jul 18 2019 CentOS-Base.repo
-rw-r--r-- 1 root root 230 Jul 18 2019 epel.repo
-rw-r--r-- 1 root root 675 Jul 18 2019 yum.repos.d/CentOS-Base.repo
-rw-r--r-- 1 root root 230 Jul 18 2019 yum.repos.d/epel.repo
查询fcscanf文件并变成.bak结尾的文件
➜ /etc find fcscanf
fcscanf
➜ /etc find fcscanf -exec mv {} {}.bak \;
➜ /etc find *.bak
fcscanf.bak
nsswitch.conf.bak
➜ /etc
递归查找所有文件内容中包含hello world的xml文件
find . -name "*.xml" | xargs grep "hello world"
删除文件大小为零的文件
find ./ -size 0 | xargs rm -f &
逻辑查询
-a 并且
-o 或者
+ 高于
- 低于
查看 .sh或者.q结尾的文件。
➜ test find . -name "*.sh" -o -name "*.q"
./book.q
./stop.sh
./start.sh
查看.sh结尾并且s开头的文件。
➜ test find . -name "*.sh" -a -name "s*"
./stop.sh
./start.sh
在文件中插入内容后查看。
➜ test ll
总用量 12K
-rw-r--r-- 1 root root 9 11月 4 15:10 book.q
-rw-r--r-- 1 root root 13 11月 4 15:10 start.sh
-rw-r--r-- 1 root root 4 11月 4 15:10 stop.sh
-rw-r--r-- 1 root root 0 11月 4 14:56 xq1.txt.bak
-rw-r--r-- 1 root root 0 11月 4 14:56 xq2.txt.bak
-rw-r--r-- 1 root root 0 11月 4 14:56 xq.txt.bak
查看/etc 大于40k小于50k的文件
➜ test find /etc/ -size +40k -a -size -50k
/etc/selinux/targeted/active/modules/100/sysadm/hll
/etc/selinux/targeted/contexts/files/file_contexts.homedirs.bin
按类型和时间查询
sudo -u admin find /home/admin /tmp /usr -name \*.log(多个目录去找)
find . -iname \*.txt(大小写都匹配)
find . -type d(当前目录下的所有子目录)
find /usr -type l(当前目录下所有的符号链接)
find /usr -type l -name "z*" -ls(符号链接的详细信息 eg:inode,目录)
find /home/admin -size +250000k(超过250000k的文件,当然+改成-就是小于了)
find /home/admin f -perm 777 -exec ls -l {} \; (按照权限查询文件)
find /home/admin -atime -1 1天内访问过的文件
find /home/admin -ctime -1 1天内状态改变过的文件
find /home/admin -mtime -1 1天内修改过的文件
find /home/admin -amin -1 1分钟内访问过的文件
find /home/admin -cmin -1 1分钟内状态改变过的文件
find /home/admin -mmin -1 1分钟内修改过的文件
查询当前目录下所有的 markdown 文档:
$ find . -name "*.log"
查询用户视频文件夹中大于 100M 的文件:
$ find ~/Videos/ -size +100M
查询用户音乐文件夹中过去七天访问过的文件:
$ find ~/Music/ -atime -7
查询系统中、三个月之前创建的、一个月之内没有访问过、大于 30M 的日志文件,并删除:
find / -ctime +90 -atime +30 -size +1M -name "*.log" -delete