网上搜索find命令的用法,我去,全是什么搜索跟时间,跟权限相关的用法,我TM不是运维也不是系统管理员,不要跟我讲find的35种用法,我不关心这些啊。花了半天时间,N多篇关于find命令用法的文章看完,发现还是不能解决问题,只能说我愚钝啊。我只想用find来查找和查看代码,谁懂我啊~~~
本篇主要是码农的日常find
用法收集,所以,如果你是想基于各种时间,用户和权限等进行文件查找,抱歉,本篇并未涉及。
免不了啰嗦一下,“find”的常用的几个选项:
-name
,按照指定文件名称查找-iname
,按照指定文件名称查找,并忽略大小写-type
,按照指定文件类型查找-mindepth/maxdepth
,指定查找的深度-size
,指定查找文件大小-exec
,对查找结果进行指定操作-a/-o
,多个条件合并查找-prune
,指定排除查找的条件
1. 使用文件名进行查找
使用文件名查找文件
查找
u-boot
目录下包含rpi
的文件:ygu@guyongqiangx:u-boot-2016.09$ find . -name *rpi* ./configs/rpi_2_defconfig ./configs/rpi_defconfig ./configs/rpi_3_defconfig ./configs/rpi_3_32b_defconfig ./board/raspberrypi/rpi ./board/raspberrypi/rpi/rpi.c ./include/configs/rpi.h
这里没有指定只查找文件,所以搜索结果中
./board/raspberrypi/rpi
是目录。使用文件名查找文件,并忽略大小写
查找
rootfs
目录下所有名为makefile
的文件,并忽略大小写:ygu@guyongqiangx:linux-3.14-1.5$ find rootfs -iname makefile ... rootfs/user/gptfdisk/makefile rootfs/user/snmpd/Makefile rootfs/user/snmpd/snmplib/Makefile rootfs/user/snmpd/modules/Makefile rootfs/user/snmpd/snmpd/Makefile rootfs/user/fileutils/Makefile rootfs/user/stty/Makefile rootfs/user/inetd/Makefile rootfs/user/cramfs/Makefile rootfs/user/cksum/Makefile rootfs/user/tftpd/Makefile rootfs/user/dhrystone/Makefile ...
使用文件名查找文件,并指定查找目录深度
查找
rootfs
目录和其一级子目录下的makefile
ygu@guyongqiangx:linux-3.14-1.5$ find rootfs -mindepth 1 -maxdepth 2 -iname makefile rootfs/host/Makefile rootfs/Makefile rootfs/lib/Makefile rootfs/config/Makefile rootfs/user/Makefile
使用文件名查找文件,并在查找结果上执行特定操作
查找
rootfs
目录下所有编译生成的kernel文件,并计算其md5
校验和ygu@guyongqiangx:linux-3.14-1.5$ find rootfs -iname vmlinuz* -exec md5sum {} \; 928dba467dd79b8b554ff7c3db9eca95 rootfs/images/vmlinuz-7439b0 c82736b02abe048c633df0923b0ee521 rootfs/images/vmlinuz-initrd-7439b0
查找
rootfs
目录下所有编译生成的kernel文件,并重命名备份ygu@guyongqiangx:linux-3.14-1.5$ find rootfs -iname vmlinuz* -exec mv {} {}.bak.20170610 \; ygu@guyongqiangx:linux-3.14-1.5$ find rootfs -iname vmlinuz* rootfs/images/vmlinuz-initrd-7439b0.bak.20170610 rootfs/images/vmlinuz-7439b0.bak.20170610
查找名为的
libmediaservice
文件夹$ ygu@guyongqiangx:972604/android$ find . -type d -name libmediaplayerservice ./frameworks/av/media/libmediaplayerservice
2. 忽略查找中的错误信息
将查找中的错误信息重定向到/dev/null
$ ygu@guyongqiangx:/local/users$ find . -type f -name android-6.0.1_*.tgz 2>/dev/null
$ find /etc -name auto.* -print 2>/dev/null
3. 按文件大小进行查找
查找当前目录下所有大于100MB的ISO文件
ygu@guyongqiangx:/public/ygu$ find server -iname *.iso -size +100M
server/ubuntu-14.04.5-desktop-amd64.iso
server/ubuntu-16.04.2-desktop-amd64.iso
4. 对特定路径模式的查找
查找所有路径中包含tests的目录下的*.dts文件:
ygu@guyongqiangx:u-boot-2016.09$ find . -name *.dts -path "*/tests/*"
./test/py/tests/vboot/sandbox-kernel.dts
./test/py/tests/vboot/sandbox-u-boot.dts
选项-path "*/tests/*"
指定文件路径中包含tests
的文件
查找路径中包含”tools”或”lib”的*.py文件:
ygu@guyongqiangx:u-boot-2016.09$ find . -name *.py \( -path "*/dtoc/*" -o -path "*/lib/*" \)
./lib/libfdt/test_libfdt.py
./lib/libfdt/setup.py
./tools/dtoc/fdt_util.py
./tools/dtoc/fdt.py
./tools/dtoc/dtoc.py
./tools/dtoc/fdt_fallback.py
使用-o
连接两个-path
选项限定查找的路径匹配模式(路径包含”dtoc”或”lib”)。
5. 在find
结果中进行grep
操作
ygu@guyongqiangx:linux-3.14-1.5$ find linux -name "*.c" | xargs grep functionname
6. 使用-prune
进行排除性查找
选项-prune
适用于排除性查找,最初接触find
命令时感觉较难。
之所以难理解,是因为我们一般习惯语法格式为-prune xxx
的用法,即在-prune
后跟xxx
来指明排除的条件,但实际上却刚好相反,-prune
的排除条件需要写在前面,我曾经为这个用法迷糊了好久。
这里以Android中文件build/envsetup.sh
内对find
的使用来看-prune
的用法:
指定文件中进行
grep
function cgrep() { find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f \( -name '*.c' -o -name '*.cc' -o -name '*.cpp' -o -name '*.h' -o -name '*.hpp' \) \ -exec grep --color -n "$@" {} + }
函数
cgrep
仅在当前目录下C/C++相关的*.{c, cc, cpp, h, hpp}
后缀的文件中进行grep
查找:- 使用
-prune
排除多个目录,条件‘-name .repo -prune’
,‘-name .git -prune’
,‘-name out -prune’
分别排除名称为.repo
,.git
和out
的目录,各个排除目录的条件为”或”,使用‘-o’
连接 - 查找多个后缀的文件名,条件
-name '*.c'
,-name '*.cc'
,-name '*.cpp'
,-name '*.h'
,-name '*.hpp'
分别包含后缀为*.{c, cc, cpp, h, hpp}
的文件,各个查找的文件名的条件为“或”,使用‘-o’
连接 - 对符合后缀的文件中进行
grep
操作:-exec grep --color -n "$@" {} +
对于
-exec
操作,有两种形式:-exec command
-exec command {} +
这两种操作的主要差别在+
上,没搞懂有+
和没有+
的区别,哪位大神来指导下?万分感谢!
- 使用
查找并导入指定目录下的
vendorsetup.sh
脚本# Execute the contents of any vendorsetup.sh files we can find. for f in `test -d device && find -L device -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort` \ `test -d vendor && find -L vendor -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort` \ `test -d product && find -L product -maxdepth 4 -name 'vendorsetup.sh' 2> /dev/null | sort` do echo "including $f" . $f done
以上操作会先检查
{device, vendor, product}
目录是否存在,如果存在,在其目录下查找vendorsetup.sh
文件,并将其用.
操作包含到当前的命令行环境中来。-L
选项表示会进入符号链接内的文件夹下查找-maxdepth 4
选项指定查找深度不超过4层,所以自定义平台vendorsetup.sh
脚本的时候,存放深度不要太深了啊~~不然找不到哦~
godir
函数中查找文件,但忽略out
和.repo
目录find . -wholename ./out -prune -o -wholename ./.repo -prune -o -type f > $FILELIST
这里的
-wholename ./out
和-wholename ./.repo
等同于-path ./out
和-wholename ./.repo
,由于有-prune
后缀,所以相当于排除这两个目录
7. 一些练习
在linux目录中查找所有的*.h
,并在这些文件中查找“SYSCALL_VECTOR
”,最后打印出所有包含”SYSCALL_VECTOR
“的文件名
- 在头文件中查找”
SYSCALL_VECTOR
”
ygu@guyongqiangx:linux-3.14-1.5$ find linux -name *.h | xargs grep "SYSCALL_VECTOR"
linux/arch/x86/include/asm/irq_vectors.h:#define IA32_SYSCALL_VECTOR 0x80
linux/arch/x86/include/asm/irq_vectors.h:# define SYSCALL_VECTOR 0x80
linux/arch/m32r/include/asm/syscall.h:#define SYSCALL_VECTOR "2"
linux/arch/m32r/include/asm/syscall.h:#define SYSCALL_VECTOR_ADDRESS "0xa0"
- 只显示包含”
SYSCALL_VECTOR
“的头文件名
ygu@guyongqiangx:linux-3.14-1.5$ find linux -name *.h | xargs grep -l "SYSCALL_VECTOR"
linux/arch/x86/include/asm/irq_vectors.h
linux/arch/m32r/include/asm/syscall.h
grep
的-l
选项只显示搜索的文件名
我会根据读代码时运用的find
操作,不定时对本文进行更新,十分欢迎大神秀出你的绝技,让大家能够受益。