grep显示包含包含string的文件的文件夹

我需要在我的服务器上运行grep来search扩展CodeIgniter 1文件的文件,因为我们正在升级到CI2。 在一个文件夹中包含几百个特定于站点的文件夹,例如:

dev/sitea.com/site/www dev/siteb.com/site/www dev/sitec.com/site/www ... and so on 

我如何grepfind哪些文件夹直接在dev下包含一个文件(或许多文件在variables的子文件夹中)引用string“MY_Output”(PHP文件)

我知道-l标志列出的文件,但我不知道如何把它与其他标志在一起说:“ 告诉我哪些网站包含这个string的文件

这可能吗? 谢谢!

编辑:只是为了澄清,这些网站级文件夹将包含扩展MY_Output.php,这是一个共同的共享文件的文件:

 class Whatever extends MY_Output 

这将是我的方法:

 find dev -type f -print0 | \ # find all files xargs -0 grep 'extends MY_Output' | \ # search for your string cut -d/ -f2 | \ # extract web folder name sort | uniq # eliminate duplicates 

请注意使用print0参数find xargs-0 (零)标志,这样可以防止在文件名中embedded空格时出现问题。

在发布的各种解决scheme中,我看到很多不必要的复杂性。 考虑以下:

 grep -r [regex to find] [path to search] | awk -F: '{print $1}' | uniq 

要找出哪些网站中有一个带有MY_output.php的文件,请按照以下步骤操作:

使用PuTTYlogin到服务器。 你应该得到这样的命令提示符:

 username@hostname:~$ 

切换到你的开发目录(不知道这是在你的服务器上,也许在/ var / www?)

 cd /var/www/dev 

确保我们在正确的目录中

 ls 

我们应该得到这样的东西:

 sitea.com siteb.com sitec.com 

现在find每个包含MY_output.php的文件,然后将列表缩小到域:

 grep -rsl "extends MY_output" * | cut -d/ -f1 | sort | uniq 

Grep在所有Web目录中recursion地查找所有匹配的文件。 cut命令打破了你的path,只是给出第一个目录名(sitea.com,siteb.com等)sort和uniq命令只是删除重复的条目,所以每个域只出现一次。

请享用!

使用find来列出所有文件,然后在每个文件上运行grep:

 find dev/ | xargs grep -l MY_Output.php 

注意 :您必须位于包含dev目录的目录中

如果你得到不可读文件的错误(权限等),那么你可以附加2>/dev/null

 find dev/ | xargs grep -l MY_Output.php 2>/dev/null 

你可能可以用grep来做到这一点,但我认为所需的逻辑certificate了使用脚本的合理性…这是一个快速的Python脚本,将根据你提供的参数进行search…

首先从ROOT_DIRECTORYrecursionsearch任何匹配FILE_FILTER文件,然后search每个文件中与SEARCH_STRING匹配的string。 如果find与SEARCH_STRING匹配的任何文件,它将logging匹配,并立即跳过该目录中的剩余文件,移动到all_files中尚未匹配的下一个文件(节省一些CPU和磁盘损耗)。

如果我做了不正确的假设,可以编辑名为FILE_FILTERSEARCH_STRINGROOT_PATH的variables。

将下面的脚本保存为searchme.py并使用python searchme.py执行

===

 import os import re import sys def get_directory(path): return '/'.join(path.split('/')[0:-1]) FILE_FILTER = '(\.htm|\.php)' SEARCH_STRING = 'MY_Output' ROOT_PATH = '~/' all_files = [] retval = {} rootdir = os.path.expanduser(ROOT_PATH) ## Find all files matching FILE_FILTER for root, subFolders, files in os.walk(rootdir): for file in files: pname = os.path.join(root,file) if re.search(FILE_FILTER, pname) is not None: all_files.append(pname) retval[get_directory(pname)] = False ## Search files for SEARCH_STRING; take shortcut if string is found for pname in all_files: path = get_directory(pname) if not retval[path]: try: for line in open(pname): if SEARCH_STRING in line: retval[path] = True; break except IOError: ## Occasionally firefox makes lock files that can't be opened... ## Ignore any permission errors... pass ## Print resultant directories... for path in sorted(retval.keys()): if retval[path]: print path 

如果你login你的服务器,然后cd到开发文件夹,这应该工作:

 egrep -rl 'class \S+ extends MY_Output' * | awk -v FS="/" '{print $2}' | sort | uniq -c 

这将只接收实际上有扩展MY_Output类的类的网站,它也会给你一个你希望改变的网站文件的数量。 您也可以使用剪切实用程序而不是awk:

 egrep -rl 'class \S+ extends MY_Output' * | cut -d/ -f2 | sort | uniq -c 

据我了解,一般来说,你想列出哪些文件夹包含名为dev / * / * ,其本身包含string“ MY_Output ”(区分大小写)的常规文件。

更确切地说,由于“*”模式不匹配以“。”开头的文件或目录,因此您还需要searchdev / * / *dev /.??*/*,dev / * /。 ?*dev /.??*/.??* 。 这是秘密和Brian Showalter的解决scheme所缺less的细节。

使用这四种模式可以确保您处理所有您想要的文件,并且不会从其他(更深或更浅)的文件中获得额外的匹配。 通常情况下,匹配文件的列表可以简单地通过运行:

 grep -l MY_Output dev/*/* dev/.??*/* dev/*/.??* dev/.??*/.??* 2>/dev/null 

2> / dev / null部分在那里可以忽略错误,比如当你尝试从没有权限的文件中读取文件时,就像你在做什么(根据你对Imre L的答案的回答)。 为获得最佳效果,您可能需要以root用户身份运行此命令。

不幸的是,命令行长度是有限制的,如果匹配文件太多,这个命令可能会失败,因为命令行太长了(扩展后)。 既然你说在dev下有数百个目录,这种方法是不合适的,尽pipe我认为在这里完整性是值得一提的。

为了避免这个问题, find命令更适合:

 find dev -mindepth 2 -maxdepth 2 -type f \ -exec bash -c 'grep -q MY_Output {} && echo {}' \; 

这与Imre L给出的答案非常相似,尽pipe他使用了xargs而不是使用-exec开关。 但是,这只能得到匹配文件的列表,而不是包含那些文件夹的列表。

为了得到你想要的东西,我们需要进一步过滤一下:

 find dev -mindepth 2 -maxdepth 2 -type f \ -exec bash -c 'grep -q MY_Output {} && dirname {}' \; \ | sort \ | uniq 

-mindepth-maxdepth开关确保我们不会从开发树中更深或更浅的文件获得匹配。

我想我会做这样的事情:

 for dir in dev/* ; do if [ -d "$dir" ] ; then if [ -n "$( find "$dir" -type f \ -exec grep -q '\<MY_Output\>' {} \; \ -print | head -1 )" ] ; then echo "$dir" fi fi done 

或者,作为一个单行的:

 for dir in dev/* ; do [ -d "$dir" ] && [ -n "$( find "$dir" -type f -exec grep -q '\<MY_Output\>' {} \; -print | head -1 )" ] && echo "$dir" ; done 
 find (Directory) -iname "(File Pattern>)" -exec zgrep "(String to Find)" {} \; 

例如:

 find /opt/WebSphere/AppServer/profiles/application/logs/ -iname "SystemOut*" -mtime -7 -exec zgrep "FileNotFoundException" {} \;