[译]GrepWrap-GNU Grep的Windows包装器
By robot-v1.0
本文链接 https://www.kyfws.com/applications/grepwrap-a-windows-wrapper-for-gnu-grep-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 15 分钟阅读 - 7428 个词 阅读量 0[译]GrepWrap-GNU Grep的Windows包装器
原文地址:https://www.codeproject.com/Articles/53301/GrepWrap-A-Windows-Wrapper-for-GNU-Grep
原文作者:Harold Bamford
译文由本站 robot-v1.0 翻译
前言
A GUI wrapper for the GNU command-line tool, Grep, used to search folders of text/code files
GNU命令行工具Grep的GUI包装器,用于搜索文本/代码文件的文件夹
目录(Table of Contents)
-
致谢和参考(Acknowledgements and References) ## 修订记录(Revision History)
-
1.0至1.2版-仅供个人使用的版本(Versions 1.0 to 1.2 – Personal use only versions)
-
版本1.3-初始(Version 1.3 – Initial)施加于(inflicted upon)发布到CodeProject(release to CodeProject)
-
1.4版-已取代(Version 1.4 – Replaced)**demo.zip(demo.zip)**具有可安装的(和新名称)(with an installable (and new name))
-
1.5版-添加了``程序'‘菜单项以指示(Version 1.5 – Added ‘Programs’ menu item to indicate location of)程序(grep.exe),杂项清除(, misc cleanup)
-
1.6版-修复了没有默认系统处理程序的文件的错误(Version 1.6 – Fixed a bug with files that don’t have a default system handler) ## 介绍(Introduction)
我一直都找到命令行实用程序(I have always found the command-line utility)grep(grep)对蛮力搜索文本文件中的模式(尤其是代码源!)很有用,但是选项的数量令人望而生畏,当搜索完成时,我总是必须手动找到匹配的文件并打开并滚动到正确的行.好像我在想什么.(to be useful for brute-force searching of patterns in text files (especially code source!), but the number of options is daunting and when the search is finished, I always have to manually find the matching file and open it up and scroll to the correct line. It just seemed that I was missing something.)
以上是(The above is)**略(slightly)**更容易理解为:(more easily read as:)
grep --with-filename --line-number -C2 --devices=skip --color=always \
--binary-files=without-match -P --recursive -i --exclude-dir='Debug' \
--exclude-dir='Release' --regexp='toolbar.*color' --include="*.cpp" \
--include="*.c" --include="*.h" .
接下来是输出(带有颜色).(followed by the output (with coloring).)
这是在当前目录中对C/C ++文件的递归搜索,避免了(This is a recursive search in the current directory for C/C++ files, avoiding the)**发布(Release)**和(and)**除错(Debug)**目录,用于模式’(directories, for the pattern ‘)工具栏.颜色(toolbar.color)'.输出具有颜色和上下文以帮助识别匹配项.在的第76行找到匹配项(’. The output has coloring and context to help identify the match. There was a match found on line 76 of)MainFrm.cpp(MainFrm.cpp).我觉得这很清楚.(. I find this clear as mud.)
所以我的解决方案是(So my solution is) GrepWrap
,这只是一个简单的包装器(, which is just a simple wrapper around) GNU Grep(GNU Grep) .(.)注意(Note):在本文的原始版本中,我使用的是该名称(: in the original version of this article, I was using the name) GrepWin
,与TortoisesVN的另一个工具相同.(, which is the same as another tool by TortoisesVN.)
它与其他具有类似名称的程序无关,例如(It has nothing to do with other programs with similar names, such as) 乌龟VN grepWin(TortoisesVN grepWin) 要么(or) Windows Grep(Windows Grep) .实际上,直到我开始写这篇文章之前,我才隐约意识到其中一些.但是,我看了看它们,尽管它们似乎是很好的工具,但它们并不能满足我的特殊需求.(. In fact, until I started to write this article, I was only vaguely aware of some of these others. However, I have looked at them and they do not meet my particular needs, although they seem to be fine utilities.)
注意:(Note:)我做(I do)不(not)包括(include)**程序(grep.exe)**在本文中,因为可以通过安装免费获得(in this article as it is freely available by installing) 西格温(Cygwin) .我强烈建议您安装Cygwin,即使您对(. I strongly suggest installing Cygwin even if you have no interest in) GrepWrap
因为它有数百个从世俗运行的非常有用的实用程序(as it has hundreds of incredibly useful utilities running from the mundane)awk(awk)程序到完整的X-Windows服务器!而且价格合适…(program to a complete X-Windows server! And the price is right…)
我来自Unix背景,在该背景下,使用命令行工具而非GUI是正常的操作模式.当我将工作换成现在的雇主时,我发现自己在一家Microsoft商店中.我是一条鱼,没水了.我有(I come from a Unix background where the use of command-line tools rather than a GUI was the normal mode of operation. When I changed jobs to my current employer, I found myself in a Microsoft shop; I was a fish out of water. I had) MKS工具包(MKS Toolkit) 在我的家用PC上,但是我的公司对在公司上花这么多钱不感兴趣.随后,我发现了Cygwin-大量移植到Windows环境的Unix工具. (Cygwin现在说他们正在仿真Linux环境,但对我来说它看起来像Unix).因此,我再次获得了提高生产力的工具集.但是在Windows环境下,我非常喜欢为所有内容提供GUI的趋势.甚至还有一个用于更改目录的GUI! (文件管理器)(on my home PC but my company wasn’t interested in spending that kind of money on me at work. I subsequently discovered Cygwin–a large collection of Unix tools ported to the Windows environment. (Cygwin now says that they are emulating a Linux environment, but it looks like Unix to me). So I have my productivity enhancing toolset back again. But staying in the Windows environment, I became very fond of the tendency to have a GUI for everything. There’s even a GUI for changing directories! (File Explorer))
我可以找到用于搜索文件的最接近的GUI是Windows桌面搜索.这个速度相当快,但是有一些问题,例如没有正则表达式,没有匹配行的上下文预览,没有办法在感兴趣的行打开匹配文件等.我在Code Project上找到了许多程序来模拟(The closest GUI I could find for searching through files was Windows Desktop Search. This was agreeably fast, but had its problems such as no regular expressions, no context preview of matching lines, no way to open the matching file at the line of interest, etc. I found a number of programs here on Code Project that emulated)grep(grep)或称为(or called)grep(grep)从命令行,但是虽然有趣,但这并不是我想要的.(from the command line, but while intriguing, were not what I wanted.)
因此,我决定编写自己的包装器.那有多难?只需两次停放,放出少量的代码即可完成.著名的遗言吧?(So I decided to write my own wrapper. How hard could that be? Just double-park, blast out the trivial amount of code, and be done with it. Famous last words, right?)
使用(Using) GrepWrap
很容易.基本上,您选择用于搜索文件的起始文件夹.如果您以前去过那里,则可以从下拉列表中选择文件夹. (很抱歉,一次只能有一个起始文件夹,没有通配符.)您可以剪切和粘贴文件夹名称,或使用``选择文件夹'‘按钮浏览它.(is easy enough. Basically, you select the starting folder for searching for files. If you have been there before, you can select the folder from a drop-down list. (Sorry, only one starting folder at a time and no wildcards.) You can Cut & Paste the folder name, or browse for it using the Select Folder button.)
“搜索"模式是Perl样式的正则表达式.如果以前使用过该模式,则在下拉列表中可用.(The “Search” pattern is a Perl-style regular expression. If you have used the pattern before, it is available in the drop-down list.)
“包含文件"仅列出要搜索的那些文件模式(窗口样式的文件模式).如果您倾向于浏览源代码树,则类似(“Include Files” lists just those file patterns (Window-style file patterns) to search. If you tend to scan through a tree of source code, a pattern like) *.c;*.cpp;*.h
可以胜任.以前使用的模式可通过下拉列表获得.如果未列出任何文件,则将搜索所有文件(二进制文件和设备除外).(may do the job. Previously used patterns are available through the drop-down list. If no files are listed, then all are searched (except binaries and devices).)
如果要排除某些文件模式,也可以这样做.更重要的是,如果您不想递归到这些目录,则也可以列出它们.例如,在搜索源代码时,我通常不想递归到(If you want to exclude certain file patterns, you can do that too. More importantly, if there are directories that you do not want to recurse into, you can list them also. For instance, when searching source code, I generally don’t want to recurse into the)除错(Debug)要么(or)发布(Release)目录.或备份目录.或Eclipse的.metadata目录等,(directories. Or the backup directory. Or Eclipse’s .metadata directory, etc.,)嗅觉(aud nauseum).这确实可以加快搜索速度.二进制文件会自动跳过;此工具适用于文本文件.只是通过Word搜索没有任何好处((. This can really speed up the search. Binary files are skipped automatically; this tool is intended for text files. It just isn’t any good for searching through Word () .doc(.doc))或Excel(() or Excel ()*** .xls(**.xls*)**)文件.为此,您还需要其他东西.(*) files. For that, you need something else.*)
最后,还有选项.通常,在您无法记住感兴趣的行是否具有例如” posix"或” POSIX"的情况下,唯一感兴趣的是"无封面"模式.(Finally, there are the options. Usually, the only one of interest is “Caseless” mode for those times when you cannot remember if the line of interest had, for instance, “posix” or “POSIX”.)
最后,按"搜索"按钮开始搜索.(At long last, press the “Search” button to start the search.)注意:(Note:)根据设计,输入<(By design, entering a <) Carriage-Return
>在一个字段中(> in a field will)不(not)开始搜索.在设置所有内容之前,我无意间开始了一次搜索.(start the search. Too many times, I accidentally started a search before I had set everything up.)
例如,假设我想为工具栏设置东西,并且我知道我有一些执行此操作的代码.所以我搜索" TOOLBAR",它是:(For example, suppose I want to setup stuff for the toolbar and I know I have some code that does this. So I search for “TOOLBAR” and there it is:)
与正则表达式的匹配项以红色显示,并且带有"(The match to the regular expression is shown in red and lines that have a “) --
“显示上下文.我可以双击感兴趣的行(上下文或匹配行),默认应用程序将打开.如果该应用程序是其中之一(” show a context. I can double-click on the line of interest (either context or matching line) and the default application will open. If that application is one of the ones) GrepWrap
知道,光标放在感兴趣的行上.(knows about, the cursor is placed on the line of interest.)
## GrepWrap已知的应用程序(Applications Known to GrepWrap)
还已知许多其他应用(There are also a number of other applications known to) GrepWrap
,并可以通过上下文菜单访问.列表很短,但是通过代码修改添加新列表很容易.(, and accessible via the context menu. The list is short but it is easy enough to add new ones via code modification.)
现在,应用程序列表(Right now, the list of applications that) GrepWrap
裁缝相当有限:(will tailor is fairly limited:)
- 安装程序(devenv.exe)(Visual Studio 2003/2005/2008,也许还有2010)((Visual Studio 2003/2005/2008, and probably 2010))
- XEmacs.exe(XEmacs.exe)(是的,我就是其中之一…)((yes, I’m one of those…))
- CodeWright.exe(CodeWright.exe)
- UltraEdit.exe(UltraEdit.exe)
- 记事本(Notepad.exe)(忽略行号,对不起)((ignores the line number, sorry)) 注意:(Note:)这些程序的默认位置是硬编码的,但是可以在注册表中覆盖.(The default locations for these programs are hard-coded, but can be overridden in the registry.)
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Scientific Atlanta\GrepWrap\Settings]
"Grep Pathname"="\"C:\\cygwin\\bin\\grep.exe\""
"XEmacs Pathname"="\"C:\\Program Files\\XEmacs\\
XEmacs-21.4.22\\i586-pc-win32\\gnuclientw.exe\""
"UltraEdit Pathname"="\"C:\\Program Files\\UltraEdit\\uedit32.exe\""
"Notepad Pathname"="\"C:\\WINDOWS\\system32\\notepad.exe\""
或者,您可以将感兴趣的行拖到目标上,并且文件将随该目标一起打开(当然,假设它支持拖放).如果放在文件资源管理器中,则将文件副本复制到显示的目录中.(Or you can drag the line of interest to a target and the file will be opened with that target (assuming it supports Drag & Drop, of course). In the case of dropping on File Explorer, a copy of the file is made into the directory that was displayed.)
对于设置位置的特定情况(For the specific case of setting the location of)程序(grep.exe),使用"程序"菜单项:(, use the Programs menu item:)
## 添加新目标/应用程序(Adding New Targets/Applications)
为其他应用程序定制行为很容易.只需查看消息映射并为该函数添加适当的声明以打开应用程序和该函数即可处理上下文菜单:(It is easy enough to tailor the behavior for other applications. Just look at the message map and add appropriate declarations for the function to open the application and the function to handle the context menu:)
ON_COMMAND(ID_EDIT_OPEN_SYSTEM_DEFAULT, &CGrepWrapView::OnEditOpenSystemDefault)
ON_COMMAND(ID_EDIT_OPEN_XEMACS, &CGrepWrapView::OnEditOpenXEmacs)
ON_COMMAND(ID_EDIT_OPEN_ULTRAEDIT, &CGrepWrapView::OnEditOpenUltraEdit)
ON_COMMAND(EDIT_EDIT_OPEN_NOTEPAD, &CGrepWrapView::OnEditOpenNotepad)
ON_COMMAND(ID_EDIT_OPENUSINGCODEWRIGHT, &CGrepWrapView::OnEditOpenUsingCodeWright)
ON_UPDATE_COMMAND_UI(ID_EDIT_OPEN_SYSTEM_DEFAULT,
&CGrepWrapView::OnUpdateEditOpenSystemDefault)
ON_UPDATE_COMMAND_UI(ID_EDIT_OPEN_XEMACS, &CGrepWrapView::OnUpdateEditOpenXEmacs)
ON_UPDATE_COMMAND_UI(ID_EDIT_OPEN_ULTRAEDIT,
&CGrepWrapView::OnUpdateEditOpenUltraEdit)
ON_UPDATE_COMMAND_UI(EDIT_EDIT_OPEN_NOTEPAD, &CGrepWrapView::OnUpdateEditOpenNotepad)
ON_UPDATE_COMMAND_UI(ID_EDIT_OPENUSINGCODEWRIGHT,
&CGrepWrapView::OnUpdateEditOpenUsingCodeWright)
该程序的默认路径名也需要定义.(Default pathnames to the program also need to be defined.)
// configurable pathnames for common programs to open a file.
// These show up in the context menu
CString m_grepPath;
CString m_xemacsPath;
CString m_ultraeditPath;
CString m_notepadPath;
CString m_codewrightPath;
以及获取最新版本路径名的代码:(And the code to get the latest version of the pathnames:)
m_grepPath = AfxGetApp()->GetProfileString("Settings", "Grep Pathname",
"\"C:\\cygwin\\bin\\grep.exe\"");
m_xemacsPath = AfxGetApp()->GetProfileString("Settings", "XEmacs Pathname",
"\"C:\\bin\\XEmacs\\XEmacs-21.4.19\\i586-pc-win32\\gnuclientw.exe\"");
m_ultraeditPath = AfxGetApp()->GetProfileString("Settings", "UltraEdit Pathname",
"\"C:\\Program Files\\UltraEdit\\uedit32.exe\"");
m_notepadPath = AfxGetApp()->GetProfileString("Settings", "Notepad Pathname",
"\"C:\\WINDOWS\\system32\\notepad.exe\"");
m_codewrightPath = AfxGetApp()->GetProfileString("Settings", "CodeWright Pathname",
"\"C:\\Program Files\\CodeWright\\cw32.exe\"");
// Ensure there are entries in the registry so we can change them as needed.
AfxGetApp()->WriteProfileString("Settings", "Grep Pathname", m_grepPath);
AfxGetApp()->WriteProfileString("Settings", "XEmacs Pathname", m_xemacsPath);
AfxGetApp()->WriteProfileString("Settings", "UltraEdit Pathname", m_ultraeditPath);
AfxGetApp()->WriteProfileString("Settings", "Notepad Pathname", m_notepadPath);
AfxGetApp()->WriteProfileString("Settings", "CodeWright Pathname", m_codewrightPath);
然后定义适当的代码以打开应用程序.这是代码(Then define the appropriate code to open the application. Here is the code for) CodeWright
:(:)
void CGrepWrapView::OnEditOpenUsingCodeWright()
{
CString filename; // name of the file to be opened, if any
int linenumber;
CString execName; // full pathname to file to execute
CString baseName; // "devenv.exe" or "vb6.exe" or the like
CString fileBase; // myprog.cpp or the like
if(!m_GetExecParameters(filename, linenumber, execName, baseName, fileBase))
{
return;
}
filename.Replace("/", "\\"); // use Windows-style separators
CString params;
params.Format("-G%d \"%s\"", linenumber, filename);
m_RunShellExec(filename, m_codewrightPath, params);// filename is ignored here
}
这是用于处理上下文菜单的代码(Here is the code for handling the context menu for) CodeWright
:(:)
void CGrepWrapView::OnUpdateEditOpenUsingCodeWright(CCmdUI *pCmdUI)
{
CString filename; // name of the file to be opened, if any
int linenumber;
CString execName; // full pathname to file to execute
CString baseName; // "devenv.exe" or "vb6.exe" or the like
CString fileBase; // myprog.cpp or the like
m_GetExecParameters(filename, linenumber, execName, baseName, fileBase);
if(filename.IsEmpty())
{
pCmdUI->SetText("Open using: CodeWright -Glinenumber filename");
pCmdUI->Enable(FALSE);
return;
}
CString msg;
msg.Format("Open using: CodeWright -G%d %s", linenumber, fileBase);
pCmdUI->SetText(msg);
pCmdUI->Enable(TRUE);
}
你在开玩笑吗?当然有错误.但我更喜欢打电话给他们(Are you kidding? Of course there are bugs. But I prefer to call them)去做(To Do)项目.(items.)
- 添加一种机制,允许用户添加任意目标应用程序(Add a mechanism to allow the user to add arbitrary target applications)
- 在下拉列表中添加修剪或清除历史记录的功能(Add the ability to trim or clear the history in the drop-down lists)
- 添加配置上下文大小(当前在匹配前后固定为3行)(Add configuration context size (currently fixed at 3 lines before and after match)) ## 兴趣点(Points of Interest)
与任何双重停车和编码项目一样,我想尝试一些事情来看看是否可以.(As with any double-park-and-code project, there were some things I wanted to try just to see if I could.)
### VBScript中的正则表达式(Regular Expressions in VBScript)
我见过但从未使用过Microsoft提供的VBScript组件中正则表达式引擎的使用.我发现(The use of the regular expression engine in the Microsoft-supplied VBScript component I had seen but never used. I found)**正则表达式(regexp.h)**和(and)**regexp.cpp(regexp.cpp)**在互联网上(如上),它就像一个魅力.它不是完整的Perl风格的正则表达式,但是可以完成工作,并且不会给应用程序增加太多负担.即使其他机制更快,我也倾向于使用正则表达式,因为我已经习惯了它们.(on the internet (attributed above) and it worked like a charm. It is not full Perl-style regular expressions, but it does the job and doesn’t add a lot of weight to the application. I tend to use regular expressions even when other mechanisms are faster just because I am so used to them.)
例如,帮助解析输出(For instance, to help parse the output of)grep(grep)(启用了颜色编码),我可以使用一系列简单的正则表达式进行测试.这是用来区分不包含匹配项而是上下文的行(这是对实际代码的解释):((with color coding enabled), I have a series of simple regular expressions that I can use for testing. This one is used to distinguish a line that does not contain a match but is context (this is a paraphrasing of the actual code):)
// When we have context lines instead of lines with a pattern match, the files
// are separated by cyan -- lines. Check for that first
m_dashRe = new RegExp;
m_dashRe->compile("^\033\\[36m--\033\\[m");
...
if(m_dashRe->exec(*line)) // compare against the current line from grep
{
...
如果您不说话,可能不清楚(This may not be clear if you do not speak)**正则表达式(regex)**要么(or)期限(termcap),但该模式只是寻找嵌入的转义码以启用青色,然后是(, but the pattern just looks for the embedded escape code to turn on the cyan color, followed by) --
然后是转义码以禁用着色.(followed by the escape code to disable coloring.)
### 管道输出流程(Piping Output from a Process)
我曾经在Unix中(在线程之前)使用一个单独的进程来执行繁重的工作并将结果传递给"主"进程,但是Joseph M Newcomer(Using a separate process to perform grunt work and passing the results to the “main” process is something I used to do in Unix (before threads), but Joseph M Newcomer’s)进程(Process.h)/(/)cpp(cpp),只需进行少量修改,就可以在这里几乎透明地执行此操作.这就是(, with minor modifications allowed me to do this almost transparently here. This is how)grep(grep)被包裹.我确实必须添加一些代码来限制来自(is wrapped. I did have to add some code to throttle output from)grep(grep)如果我仍在更新屏幕,但这并不困难.(if I was still updating the screen, but that was not terribly difficult.)
我一直想尝试Drag && Drop,但对如何操作一无所知.在这里,从中拖曳几乎很尴尬(I’ve always wanted to try out Drag & Drop but didn’t have a clue on how. Here, it was almost embarrassingly easy to drag from) GrepWrap
其他应用感谢” benbuck"(归因于此)(to other applications. Thanks to “benbuck” (attributed above) for)**dragdrop.h/.cpp(dragdrop.h/.cpp)**几乎没有修改的工作.(which worked with few modifications.)
### 丰富的编辑控件(Rich Edit Control)
但是,Rich Edit控件花费了最大的精力.我需要具有恒定宽度的字体并能够突出显示正则表达式的匹配字符.我本可以用嵌入式的Explorer控件来破解某些东西,但是我已经做到了,对此并不特别满意.对于我的需求而言,它似乎太强大了.所以我必须了解TOM((However, the most effort was expended in the Rich Edit Control. I needed to have a constant-width font and the ability to highlight the matching characters for the regular expression. I could probably have hacked something with an embedded Explorer control, but I’ve done that and not been particular happy with that. It seemed grossly over-powered for my needs. So I had to learn about TOM () IRichEditOle
东西和文本对象模型).即使添加新结果,我也必须能够滚动结果.如果操作不正确,整个屏幕将开始"颤抖"并摇晃.不太漂亮的景象.(stuff and the Text Object Model). I also had to deal with being able to scroll the results even as new results were being added. If I didn’t do it correctly, the whole screen would start to “quiver” and shake. Not a pretty sight.)
的陷阱(The gotchas for the) RichEditCtrl
分别是:(were:)
- 附加文本而不会丢失所有以前的颜色格式(Appending text without losing all previous color-formatting)
- 允许光标位置更改,同时仍附加匹配文本(Allowing cursor position to change while still appending matching text) 事实证明,这很难做到.我一点也不确信我做对了,但是似乎工作正常.(These turned out to be very hard to do. I am not at all convinced that I have got it right, but it seems to work OK.)
解析输出(Parsing the output of)grep(grep)这很繁琐,但是我能够打开输出颜色并解析特殊的转义序列以标识输出的各个部分:文件名,行号,匹配的文本(其中可能有多个!)和上下文行(前导和尾随) ).表示的颜色数(was tedious, but I was able to turn on output coloring and parse the special escape sequences to identify the various parts of the output: filename, line number, matching text (of which there might be several!) and context lines (leading and trailing). The number of colors that)grep(grep)可以输出是令人惊讶的,但是我觉得这个包装只需要黑色和红色.(can output is surprising, but I felt that just black and red were needed for this wrapper.)
## 致谢和参考(Acknowledgements and References)
盗窃(theft)
- MyRichEditCtrl.cpp(MyRichEditCtrl.cpp)/(/)**H(h)**通过Frunza Adriana,2001年9月19日(by Frunza Adriana, 19-09-2001)
- 关于的文章(An article on) 删除文件(Drop Files) 作者:Alex Rest,2003年3月28日(by Alex Rest, March 28, 2003)
- 有关流程的文章和代码(Articles and code on processes by) 约瑟夫`纽科默(Joseph M. Newcomer)
- ““的包装(A wrapper of “)
VBScript.RegExp
对于VC ++,由sswater@263.net在北京2004.3.2(” for VC++, by sswater@263.net at beijing 2004.3.2) - " benbuck"发表的文章(An article by “benbuck” on) 使用Visual Studio打开文件(opening up files with Visual Studio)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
C++ Windows 新闻 翻译