我试图找到一种方法来扫描我的OSX系统上的文件夹,查找特定行(第一行的#标签)中包含特定文本字符串(#SomeTag")的所有文件。为了澄清,我在文件中寻找文本,而不是文件名。
我想搜索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
答案 0 :(得分: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
位迭代graves中代码返回的每一行(反引号),将每一行分配到一个名为“file”的东西中。在坟墓内部,我们有find [path] -type f
,它可以找到路径中的所有“普通”文件(不包括链接,目录等),并打印将每个文件发送到stdout(由我们的for
循环使用。)
然后我们在每个文件上调用head -1
,这些文件只提取每个文件的第一行,并通过它为您的模式greps。由于我们不关心grep的正常输出,因此我将其重定向到/ dev / null以防止打印。方便的是,grep的退出代码可以被视为true / false,具体取决于它是否位于任何位置。只有当grep匹配第一行中的某些内容时,&& echo $file
才会利用此功能打印文件名。
<强>更新强> 为了支持多种模式,您可以链接上述解决方案,但最终会为您需要的每种模式打开每个文件。如果您要搜索多种模式,请尝试以下操作:
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
答案 1 :(得分:0)
我相信ctags
可以满足您的要求。它是一个使浏览大型源代码项目变得容易的工具。它提供了您在现代IDE中可能会习惯的一些功能,例如从当前源文件跳转到其他文件中的功能和结构的定义的功能。由于ctags
本质上是一个缓存的索引,因此您可以搜索任何字符串并在您的项目/目录中找到其所有引用。 Ctags设计为在Vim和Emacs内部运行。注意:fzf.vim插件具有标签搜索功能。
在您的特定情况下,您需要添加一个自定义标签。我认为ctag的regex选项就足够了:
--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。或者,最好使用fzf vim插件,该插件具有Tag
和BTag
命令。