我需要在我的服务器上运行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_FILTER , SEARCH_STRING和ROOT_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" {} \;