find + grep +xargs进行内容搜索

linux下快速查找包含指定内容的文件


linux下查找包含指定内容的文件经常需要用到两个指令,find与grep。

find命令

find的基本作用为在目录层次结构中搜索指定的文件,其基本语法如下:

find [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point...] [expression]

下面介绍常用的find用法:

 - Find files by extension:
   find {{root_path}} -name '{{*.ext}}'

 - Find files matching multiple path/name patterns:
   find {{root_path}} -path '{{**/path/**/*.ext}}' -or -name '{{*pattern*}}'

 - Find directories matching a given name, in case-insensitive mode:
   find {{root_path}} -type d -iname '{{*lib*}}'

 - Find files matching a given pattern, excluding specific paths:
   find {{root_path}} -name '{{*.py}}' -not -path '{{*/site-packages/*}}'

 - Find files matching a given size range:
   find {{root_path}} -size {{+500k}} -size {{-10M}}

 - Run a command for each file (use 
   {}
 within the command to access the filename):
   find {{root_path}} -name '{{*.ext}}' -exec {{wc -l {} }}\;

 - Find files modified in the last 7 days and delete them:
   find {{root_path}} -daystart -mtime -{{7}} -delete

 - Find empty (0 byte) files and delete them:
   find {{root_path}} -type {{f}} -empty -delete

grep命令

grep命令在指定的文件中搜索符合pattern的行,并输出
其基本语法如下:

grep [OPTIONS] PATTERN [FILE...]
grep [OPTIONS] -e PATTERN ... [FILE...]
grep [OPTIONS] -f FILE ... [FILE...]

grep的常用方法如下:

- Search for a pattern within a file:
   grep "{{search_pattern}}" {{path/to/file}}

 - Search for an exact string (disables regular expressions):
   grep --fixed-strings "{{exact_string}}" {{path/to/file}}

 - Search for a pattern in all files recursively in a directory, showing line numbers of matches, ignoring binary files:
   grep --recursive --line-number --binary-files={{without-match}} "{{search_pattern}}" {{path/to/directory}}

 - Use extended regular expressions (supports 
   ?
, 
   +
, 
   {}
, 
   ()
 and 
   |
), in case-insensitive mode:
   grep --extended-regexp --ignore-case "{{search_pattern}}" {{path/to/file}}

 - Print 3 lines of context around, before, or after each match:
   grep --{{context|before-context|after-context}}={{3}} "{{search_pattern}}" {{path/to/file}}

 - Print file name and line number for each match:
   grep --with-filename --line-number "{{search_pattern}}" {{path/to/file}}

 - Search for lines matching a pattern, printing only the matched text:
   grep --only-matching "{{search_pattern}}" {{path/to/file}}

 - Search stdin for lines that do not match a pattern:
   cat {{path/to/file}} | grep --invert-match "{{search_pattern}}"

find与grep的配合使用

当我们想要搜索当前目录下哪些文件包含所需要的内容时,我们可以将find与grep组合起来使用。
比如,当前目录结构如下:
在这里插入图片描述
想要在scripts中搜索哪些.sh中包含"make"字符,我写下以下指令进行尝试:

find . -name "*.sh" | grep "make"

但却惊讶的发现,输出为空,并没有任何输出,但这些sh文件中明明包含了“make”。
之所以出现这个问题的原因,是因为我错误理解了“|”——管道的作用,"|"会将前一个指令:

find . -name "*.sh"

的输出作为输入发送给grep指令,但是它发送的是一个整体,即将整个find的结果:

./build_armv7.sh
./build_armv8.sh
./build-linux.sh
./execute_linux_test.sh
./build_hisi3516.sh

发送给grep,grep只会从上述的结果文本中去寻找是否存在make,而不是自动解析出文件名,来一行一行的grep文件内容。
可以从以下命令语句中证明这个结论:

find . -name "*.sh" | grep "linux"

得到结果:

./build-linux.sh
./execute_linux_test.sh

正如上述所说,它是从文本中找到了包含"linux"的哪些行。
但是如何解决从每个".sh"中找到想要的信息呢,这时需要用到另一个指令xargs。

xargs

xargs一般用来获取来自上一个管道的参数,来作为下一个命令的输入,它将上一个管道的参数作为一个整体块,然后根据空格,tabs,新的一行等进行分割成多个参数,让下一个命令执行。
基本语法为:

xargs [options] [command [initial-arguments]]

xargs的常用用法如下:

- Run a command using the input data as arguments:
   {{arguments_source}} | xargs {{command}}

 - Run multiple chained commands on the input data:
   {{arguments_source}} | xargs sh -c "{{command1}} && {{command2}} | {{command3}}"

 - Delete all files with a 
   .backup
 extension (
   -print0
 uses a null character to split file names, and 
   -0
 uses it as delimiter):
   find . -name {{'*.backup'}} -print0 | xargs -0 rm -v

 - Execute the command once for each input line, replacing any occurrences of the placeholder (here marked as 
   _
) with the input line:
   {{arguments_source}} | xargs -I _ {{command}} _ {{optional_extra_arguments}}

 - Parallel runs of up to 
   max-procs
 processes at a time; the default is 1. If 
   max-procs
 is 0, xargs will run as many processes as possible at a time:
   {{arguments_source}} | xargs -P {{max-procs}} {{command}}

真正的内容检索

根据以上所学知识,我们可以真正的来实现在.sh中搜索包含make的那些文件了,输入指令:

find . -name "*.sh" | xargs grep "make"

成功获得了想要的结果:

./build_armv7.sh:make -j8 || exit 1
./build_armv8.sh:make test_time -j8 || exit 1
./build-linux.sh:cmake ..  \
./build-linux.sh:    -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchain/clang-x86_64-linux-gnu.toolchain.cmake \
./build-linux.sh:make detector_unit_test -j8 || exit 1
./build_hisi3516.sh:cmake .. \
./build_hisi3516.sh:  -DCMAKE_TOOLCHAIN_FILE=../cmake/arm.himix200.toolchain.cmake \
./build_hisi3516.sh:make -j8 || exit 1
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值