使用find查找代码文件的几个示例

网上搜索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.gitout的目录,各个排除目录的条件为”或”,使用‘-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“的文件名

  1. 在头文件中查找”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"
  1. 只显示包含”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操作,不定时对本文进行更新,十分欢迎大神秀出你的绝技,让大家能够受益。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

洛奇看世界

一分也是爱~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值