天天看點

使用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-$ 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

    的檔案,并忽略大小寫:
    [email protected]:linux--$ 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--$ find rootfs -mindepth  -maxdepth  -iname makefile   
    rootfs/host/Makefile
    rootfs/Makefile
    rootfs/lib/Makefile
    rootfs/config/Makefile
    rootfs/user/Makefile
               
  • 使用檔案名查找檔案,并在查找結果上執行特定操作

    查找

    rootfs

    目錄下所有編譯生成的kernel檔案,并計算其

    md5

    校驗和
    ygu@guyongqiangx:linux--$ find rootfs -iname vmlinuz* -exec md5sum {} \;
    dba467dd79b8b554ff7c3db9eca95  rootfs/images/vmlinuz-b
    c82736b02abe048c633df0923b0ee521  rootfs/images/vmlinuz-initrd-b
               
    查找

    rootfs

    目錄下所有編譯生成的kernel檔案,并重命名備份
    ygu@guyongqiangx:linux--$ find rootfs -iname vmlinuz* -exec mv {} {}.bak. \;
    ygu@guyongqiangx:linux--$ find rootfs -iname vmlinuz*
    rootfs/images/vmlinuz-initrd-b.bak.
    rootfs/images/vmlinuz-b.bak.
               
  • 查找名為的

    libmediaservice

    檔案夾
    $ ygu@guyongqiangx:/android$ find . -type d -name libmediaplayerservice
    ./frameworks/av/media/libmediaplayerservice
               

2. 忽略查找中的錯誤資訊

将查找中的錯誤資訊重定向到

/dev/null

3. 按檔案大小進行查找

查找目前目錄下所有大于100MB的ISO檔案

[email protected]:/public/ygu$ find server -iname *.iso -size +M
server/ubuntu--desktop-amd64.iso
server/ubuntu--desktop-amd64.iso
           

4. 對特定路徑模式的查找

查找所有路徑中包含tests的目錄下的*.dts檔案:

ygu@guyongqiangx:u-boot-$ 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檔案:

[email protected]:u-boot-$ 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--$ 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  -name 'vendorsetup.sh' > /dev/null | sort` \
           `test -d vendor && find -L vendor -maxdepth  -name 'vendorsetup.sh' > /dev/null | sort` \
           `test -d product && find -L product -maxdepth  -name 'vendorsetup.sh' > /dev/null | sort`
    do
      echo "including $f"
      . $f
    done
               
    以上操作會先檢查

    {device, vendor, product}

    目錄是否存在,如果存在,在其目錄下查找

    vendorsetup.sh

    檔案,并将其用

    .

    操作包含到目前的指令行環境中來。
    • -L

      選項表示會進入符号連結内的檔案夾下查找
    • -maxdepth 4

      選項指定查找深度不超過4層,是以自定義平台

      vendorsetup.sh

      腳本的時候,存放深度不要太深了啊~~不然找不到哦~
  • godir

    函數中查找檔案,但忽略

    out

    .repo

    目錄

    這裡的

    -wholename ./out

    -wholename ./.repo

    等同于

    -path ./out

    -wholename ./.repo

    ,由于有

    -prune

    字尾,是以相當于排除這兩個目錄

7. 一些練習

在linux目錄中查找所有的

*.h

,并在這些檔案中查找“

SYSCALL_VECTOR

”,最後列印出所有包含”

SYSCALL_VECTOR

“的檔案名

  1. 在頭檔案中查找”

    SYSCALL_VECTOR

ygu@guyongqiangx:linux--$ 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--$ 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

操作,不定時對本文進行更新,十分歡迎大神秀出你的絕技,讓大家能夠受益。

繼續閱讀