0

我正在尝试找到一种方法来扫描我的 OSX 系统上的文件夹,以查找在特定行(第一行中的井号标签)中包含特定文本字符串(#SomeTag“)的所有文件。为了澄清,我正在寻找文本在文件中,而不是在文件名中。

我尝试了agfzf以及组合,但无法使其按我想要的方式工作。

我想用fzf搜索在特定行中有一些主题标签的文件。例如:

#TagOne #TagTwo searchpattern

这将仅在第一行有 #TagOne #TagTwo 的文件中搜索 searchpattern。

更新: 到目前为止,我想出了这个可行的解决方案,但它远非最佳,但它完全符合我的要求。该脚本在找到文件后接受 1-3 个参数,我可以在所有找到的文件的内容中进行全文模糊搜索。

 #!/bin/sh
if [ "$#" == 1 ]; then
    ag -Ril $1 ./Evernote | xargs ag --nobreak --nonumbers --noheading . | fzf
fi
if [ "$#" == 2 ]; then
    ag -Ril $1 ./Evernote | xargs ag -il $2 | xargs ag --nobreak --nonumbers --noheading . | fzf
fi
if [ "$#" == 3 ]; then
    ag -Ril $1 ./Evernote | xargs ag -il $2 | xargs ag -il $3 | xargs ag --nobreak --nonumbers --noheading . | fzf
fi
4

2 回答 2

3
for file in `find [path] -type f`; do head -1 $file | grep [pattern] >> /dev/null && echo $file; done

将 [path] 替换为您要搜索的目录,将 [pattern] 替换为您要查找的任何内容,例如“#TagOne #TagTwo searchpattern”。

for file in ``; do ....; done位遍历坟墓中代码返回的每一行(反引号),将每一行分配到一个名为“文件”的东西中。在坟墓中,我们有,它会在您的路径中找到所有“正常”文件(不包括链接、目录等)并打印将每个文件发送到标准输出(我们的循环find [path] -type f正在使用它。)for

然后我们调用head -1这些文件中的每一个,它只提取每个文件的第一行,并通过它来查找您的模式。因为我们不关心 grep 的正常输出,所以我将它重定向到 /dev/null 以防止打印。方便地,grep 的退出代码可以被视为真/假,这取决于它是否找到任何东西。仅当&& echo $filegrep 匹配第一行中的某些内容时,才利用这一点打印文件名。

更新 为了支持多种模式,您可以链接上述解决方案,但您最终会为您需要的每个模式打开每个文件。如果你有很多模式要搜索,试试这个:

for file in `find . -type f`; do                                                                    
  FIRSTLINE=`head -1 $file`;                                                                      
  if [[ $FIRSTLINE == *pattern1* &&                                                                     
        $FIRSTLINE == *pattern2* &&                                                                     
        $FIRSTLINE == *pattern3* ]];
  then
      echo $file;
  fi;
done

这都可以被压缩为一行以用作别名,但我们在这里越过了 bash 不太擅长的一条线。已经设置了我们在一个不能被正则表达式限制的模式上匹配的要求,你可能最好求助于 python:

#!/usr/bin/env python
from os import walk
from os.path import join
import sys

directory = sys.argv[1]  # Use the first argument as the directory to search

for root, subdirs, files in walk(directory):
    for file in files:
        path = join(root, file)
        line = open(path).readline()
        if ('TagOne' in line and      # You could also get these on 
                'TagTwo' in line and  # the command-line...
                'TagThree' in line):
            print path
于 2017-05-25T07:19:51.693 回答
0

我相信ctags可以填补这个账单。它是一个可以轻松浏览大型源代码项目的工具。它提供了一些您在现代 IDE 中可能习惯使用的功能,例如从当前源文件跳转到其他文件中的函数和结构定义的能力。由于ctags本质上是一个缓存索引,因此您可以搜索任何字符串并在您的项目/目录中找到它的所有引用。Ctags 设计为在 Vim 和 Emacs 内部运行。注意:fzf.vim 插件有标签搜索功能。

在您的特定情况下,您需要添加自定义标签。我认为 ctag 的正则表达式选项就足够了:

--regex-<LANG>=/line_pattern/name_pattern/[flags]
       Define regular expression for locating tags in specific language.

例如,您可以递归扫描所有文本文件以查找#word,并将这些结果保存在标签文件中。首先创建一个 ctags 选项文件:

# ctags definition file for searching for tags. 
--langdef=hashtext
--map-hashtext=+.txt
--regex-hashtext=/.*(#[a-zA-Z0-9]*)/\1/h,hashtag/I   #define your regex here
--fields=+ln

举例来说,假设这个选项文件被称为 hashtext.ctags。接下来,然后在您的目录中运行 ctags,如下所示:

ctags -R --options=hashtext.ctags *

这将递归搜索正则表达式并在tags文件中创建索引。在 vim 中打开您希望通过主题标签浏览的文件并使用:tag功能。

一旦所有这些机制到位,您就可以使用 fzf 搜索并跳转到各种标签。有关详细信息和示例设置,请参见此处:fzf tags。或者,更好的是,使用具有TagBTag命令的 fzf vim 插件。

于 2018-09-22T16:34:01.070 回答