查找和回显仅具有模式的文件名


Answers:


24
find . -name '*.py' -exec grep something {} \; -print

将在匹配的行打印文件名。

find . -name '*.py' -exec grep something /dev/null {} +

会在每条匹配行的前面打印文件名(我们添加/dev/null一个匹配文件的情况,因为grep如果只传递一个文件供查看,则不打印文件名。GNU实现为此grep提供了一个-H选项作为备选)。

find . -name '*.py' -exec grep -l something {} +

将仅打印具有至少一行匹配内容的文件的文件名。

要在匹配的行之前打印文件名,可以改用awk:

find . -name '*.py' -exec awk '
  FNR == 1 {filename_printed = 0}
  /something/ {
    if (!filename_printed) {
      print FILENAME
      filename_printed = 1
    }
    print
  }' {} +

grep为每个文件调用两次-尽管效率较低,因为它将至少运行一个grep命令,每个文件最多运行两个命令(并读取文件内容两次):

find . -name '*.py' -exec grep -l something {} \; \
                    -exec grep something {} \;

无论如何,您都不想遍历findlike这样的输出,记得引用您的variable

如果要使用Shell循环,请使用GNU工具:

find . -name '*.py' -exec grep -l --null something {} + |
   xargs -r0 sh -c '
     for file do
       printf "%s\n" "$file"
       grep something < "$file"
     done' sh

(也适用于FreeBSD及其衍生版本)。


6

如果您使用的是GNU grep,则可以使用其-r--recursive选项为您执行以下简单查找:

grep -r --include '*.py' -le "$regexp" ./ # for filenames only
grep -r --include '*.py' -He "$regexp" ./ # for filenames on each match

find在需要更高级的谓词时才需要。


1
根据GNU的版本grepgrep可能会或可能不会看里面的符号链接或者遍历符号链接到目录。您可能还会发现其他类型的非常规文件的处理方式有所不同。
斯特凡Chazelas

5

您可以告诉grep在输出中包含文件名。因此,如果有匹配项,它将显示在控制台上。如果文件中没有匹配项,则不会为该文件打印任何行。

find . -name "*.py" | xargs grep -n -H something

来自man grep

-H       Always print filename headers with output lines
-n, --line-number
         Each output line is preceded by its relative line number in the file, starting at line 1.  The line number counter is reset for each file processed.
         This option is ignored if -c, -L, -l, or -q is specified.

如果文件中的名称中可能带有空格,则必须切换管道以将NUL字符用作分隔符。现在完整的命令将如下所示:

find . -name "*.py" -print0 | xargs -0 grep -n -H something


1

使用-l参数。

for file in `find . -name "*.py"`; do grep -l something $file && grep something $file; done

更常见的用法是:

for file in $(find . -name '*.py' -exec grep -l something '{}' +); do echo "$file"; grep something $file; done

1

grep默认情况下,有些替代项以所需的格式输出其结果。我知道的2种最受欢迎​​的是ag(又名“白银搜寻者”)和ackag被标榜为更快的替代产品ack

$ ag '^\w+\s*\w+\(' ~/build/i3/src
build/i3/src/display_version.c
58:void display_running_version(void) {

build/i3/src/load_layout.c
42:static TAILQ_HEAD(focus_mappings_head, focus_mapping) focus_mappings =
518:json_content_t json_determine_content(const char *filename) {
575:void tree_append_json(Con *con, const char *filename, char **errormsg) {

build/i3/src/x.c
64:CIRCLEQ_HEAD(state_head, con_state) state_head =
67:CIRCLEQ_HEAD(old_state_head, con_state) old_state_head =
70:TAILQ_HEAD(initial_mapping_head, con_state) initial_mapping_head =
97:void x_con_init(Con *con, uint16_t depth) {
...

我无法在这里显示您的信息,但输出颜色整齐。我得到的文件名是橄榄绿色,行号是金黄色,每行中的匹配部分是血红色。颜色是可定制的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.