【问题标题】:Search for files & file names using silver searcher使用 Silver Searcher 搜索文件和文件名
【发布时间】:2013-09-10 07:49:00
【问题描述】:

使用 Silver Searcher,我如何搜索:

  1. (非二进制)带有单词或模式 AND 的文件
  2. 所有文件名,带有包含二进制文件的文件名的单词或模式。

其他偏好:希望进行不区分大小写的搜索和通过点文件进行搜索。


尝试使用此别名,但运气不佳:

alias search="ag -g $1 --smart-case --hidden && ag --smart-case --hidden $1"

【问题讨论】:

标签: command-line terminal grep command-line-interface ack


【解决方案1】:

根据ag的手册页

   -G --file-search-regex PATTERN
          Only search files whose names match PATTERN.

您可以使用-G 选项对匹配某个模式的文件执行搜索。

所以,回答你的问题:

root@apache107:~/rpm-4.12.0.1# ag -G cpio.c size
rpm2cpio.c
21:    off_t payload_size;
73:    /* Retrieve payload size and compression type. */
76:     payload_size = headerGetNumber(h, RPMTAG_LONGARCHIVESIZE);

上述命令在所有匹配cpio.c模式的文件中搜索单词size

参考:
ag 版本 0.28.0 的手册页

注1:

如果您要查找特定文件类型中的字符串,比如所有 C 源代码,ag 中有一个 undocumented feature 可帮助您快速将搜索限制为特定文件类型。

以下命令都在所有 php 文件中查找 foo

find . -name \*.php -exec grep foo {}
ag --php foo

虽然find + grep 会查找所有.php 文件,但ag 命令中的--php 开关实际上会查找以下文件扩展名:

.php  .phpt  .php3  .php4  .php5  .phtml

您可以将--cpp 用于C++ 源文件,--hh 用于.h 文件,--js 用于JavaScript 等。完整列表可在here 中找到

【讨论】:

  • 很好,不知道我在提交原始答案时是如何错过-g-G 的。 OP 的措辞有点令人困惑,但我认为他想要的是运行一个搜索所有文件名以及非二进制文件内容的命令。似乎ag -g [search] && ag -l [search] 会起作用。
  • 我想这是一个更好的答案,我应该标记这个答案吗?有什么想法吗?
  • @JikkuJose 我添加了一个新答案,我相信它可以完全解决你原来的问题
  • @JikkuJose 我认为社区同意这是对您问题的更好回答。
  • -g 也值得在您的回答中占有一席之地。
【解决方案2】:

要添加到之前的答案,您可以使用"Or" Regular Expression 在匹配不同文件扩展名的文件中进行搜索。

例如,仅在 C++ 头文件 [.hpp] 和 Makefiles [.mk] 中搜索字符串):

ag -G '.*\.(hpp|mk)' my_string_to_search

【讨论】:

    【解决方案3】:

    试试这个:

    find . | ag "/.*SEARCHTERM[^/]*$"
    

    find . 命令将列出所有文件。

    我们将它的输出通过管道传递给命令ag "/.*SEARCHTERM[^/]*$",如果它在文件名中,而不仅仅是完整路径,则它与 SEARCHTERM 匹配。

    【讨论】:

    • 几乎使用更简单的解决方案解决了一个变体: ag -g 。 | ag'search_term';是的,您的模式可用于过滤文件名而不是路径。
    【解决方案4】:

    在对mdfindfindlocate 和其他尝试不满意后,以下对我有用。它使用tree 获取初始文件列表,ag 过滤掉目录,然后使用awk 打印匹配的文件本身。

    我最终使用了tree,因为它比我尝试过的其他解决方案更容易(也更容易)配置并且速度很快。

    这是一个鱼函数:

    function ff --description 'Find files matching given string'
      tree . --prune --matchdirs -P "*$argv*" -I "webpack" -i -f --ignore-case -p |
        ag '\[[^d].*' |
        awk '{print $2}'
    end
    

    这会产生类似于以下的输出:

    ~/temp/hello_world $ ff controller
    ./app/controllers/application_controller.rb
    ./config/initializers/application_controller_renderer.rb
    ~/temp/hello_world $
    

    【讨论】:

      【解决方案5】:

      尝试将此添加到您的别名文件中。使用 zsh 进行测试,但应该使用 bash。您在示例中遇到的问题是 bash 别名不能接受参数,因此您必须首先定义一个函数来使用参数,然后将别名分配给该函数。

      searchfunction() {
        echo $(ag -g $1 --hidden)
        echo $(ag --hidden -l $1)
      }
      
      alias search=searchfunction
      

      您可以通过几种方式修改此示例以适合您的目的,例如

      • 添加/删除 -l 标志,具体取决于您希望文本结果显示文本匹配还是仅显示文件名
      • 添加标题以分隔文本结果和文件名结果
      • 删除重复结果以考虑在文件名和文本等方面都匹配的文件。

      [编辑:根据 Pablo Bianchi 的评论删除了不必要的 --smart-case 标志]

      【讨论】:

      • 有什么方法可以调整它以使用 'sack/sag' (github.com/sampson-chen/sack)?这需要将两个 ag 查询合并为一个,这样 sack 所依赖的第一个命令的搜索缓存就不会被吹走。
      • 您可以省略一个参数:-S --smart-case如果PATTERN中有任何大写字母则区分大小写,否则不区分大小写。 默认启用。
      • @PabloBianchi 谢谢。我有一个(非常)旧版本的 ag,它的手册页没有“默认启用”注释,但经过测试,似乎即使旧版本的 ag 确实默认使用了这个标志。更新了我的答案。
      • 如何让它在新行上输出每个结果?
      【解决方案6】:

      自己发现这个问题正在寻找相同的答案。 ag 似乎没有任何本机功能来搜索文件和目录名称。上面来自 Zach Fogg 和 Jikku Jose 的答案都有效,但如果您在一个大目录中工作,管道 find . 可能会非常慢。

      我建议直接使用find,这比通过ag 传输要快得多:

      Linux(GNU 版本的find

      find -name [pattern]
      

      OSX(find 的 BSD 版本)

      find [pattern]
      

      如果您需要更多关于 find 的帮助,来自 Digital Ocean 的 this guide 非常好。我将其包括在内是因为如果您只想弄清楚基本用法,find 的手册页非常密集。

      【讨论】:

      • 感谢您的确认
      • @JikkuJose 您会将此作为已接受的答案删除吗?回想起来,鉴于ag 提供的-g-G 标志,这显然是不正确的
      • @Greg fyi,-g 是一个输出选项
      猜你喜欢
      • 2014-05-24
      • 2017-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-27
      • 1970-01-01
      • 2014-07-24
      相关资源
      最近更新 更多