2009-06-22 56 views
3

我正在使用这一行在我所在的目录及其所有子目录下的文件中找到短语'B206'。Unix'find'+'grep'语法与awk

find . -exec grep -s "B206" '{}' \; -print 

时候,它会读取某些文件,实际上改变腻子标题栏一堆奇怪的字符

例如经常死机,崩溃所有的时间时,命中一个jpg文件,该文件在一个子目录。标题栏发生变化,并在屏幕上存在:

ÐF»*rkNQeË+Z׳kU£~MÞçÄZ½ªéúýØâÑn¡[U+Þ4ªÒ9/ê£<ú¯4}[IÓ­îÃ¥K»G%ݳ¢ 

强迫我将Ctrl + C退出提示,然后退出。

任何方式添加代码到这一行,将排除jpg文件?更好的是,我可以添加要排除的扩展名列表的一段代码?


编辑:
- 不是& - 我不为我
工作,我发现这个 similar question也有所涉及矿山

+0

你的环境是什么?庆典? TCSH? Linux发行版? os x? – phi 2009-06-22 16:21:38

+0

如果你的系统符合POSIX标准,你可以用'!'代替`-not` 此外,如果你正在寻找的字符串总是被非单词字符(包括换行符)包围,你可以使用` -w`切换到grep [注意:这个开关不是由POSIX指定的,所以YMMV]。我也使用grep的`-H`标志来确保它打印文件名: `find。 ! -iname“* .jpeg”! -iname“* .jpg”! -iname“* .png”-exec grep -Hw B206 {} \;` – sanmiguel 2012-02-03 15:45:08

回答

3

如果您的环境不能做任何花哨的grep,也许你的awk可以做到这一点:

find . | awk '!/((\.jpeg)|(\.jpg)|(\.png))$/ {print $0;}' | xargs grep "B206" 
2
 
find . -type f -a -not -name \*.jpg -exec grep -li "string" "{}" \; 

此示例来自的Mac OSX 10.5,则需要检查发现因为GNU查找和其他供应商实现之间存在一些分歧,所以您的环境的手册页。检查的Solaris(只是为了好玩,从未指定的目标OS):

 
find . -type f -a ! -name \*.jpg -exec grep -li "string" "{}" \; 

这种结构发现,其名称不以.jpg结束,高层用grep为他们每个人的所有文件。

根据您的外壳,您可能需要逃离爆炸(!)才能使其如同广告一样工作。

+0

我得到这个错误 - “find:bad option -not” – CheeseConQueso 2009-06-22 15:50:52

+0

您需要使用gfind – DVK 2009-06-22 15:54:03

+0

-ls不能理解 - 这是坚果 – CheeseConQueso 2009-06-22 16:08:13

3

您可以使用grep的-I开关:

Process a binary file as if it did not contain matching data; 
this is equivalent to the --binary-files=without-match option. 

总之,grep的将简单地假定文件不匹配,这将保证被输出二进制数据。

+0

首先,你的名字很棒......其次,你能给我一个语法的例子吗? – CheeseConQueso 2009-06-22 15:55:29

+0

如果他的grep不支持“-not”,GNU grep似乎不太可能,并且-I是对grep的GNU加法。 – Erik 2009-06-22 16:03:59

1

如果您有权访问gfind,只需在表达式中添加“-not -name'* .jpg'”即可。

gfind . -not -name '*.jpg' -exec grep -s "B206" '{}' \; -print 

另一种选择(不需要这个任务,但一个有用的技巧),如果你想使用真正看中的正则表达式,做

找到some_easy_high_level_filter_expression -ls | perl的-pe '{/ your_Perl_RegExp_of_choice /}'> ./files_to_search_in

的grep 选项 '猫./files_to_search_in'

前行应该有反引号,但我不能让格式化程序逃脱它们

这给出了缓存文件列表有时需要的好处,以防您想要更改grep表达式来调整它或仅执行多于1个grep。

2

我试图Erik的命令,但我得到一个错误约没有-grep谓语。也许我的版本发现太旧了。

这为我工作:

find . -type f -a -not -name \*.jpg -exec grep "B206" {} \; 
8

没有理由使用findgrep配备了一个递归选项,-r。要获得带有匹配的文件名列表(与所有文件中所有匹配行的列表相反),可以使用-l选项。如果你想直接忽略所有的二进制文件,你可以使用--binary-files=without-match选项。如果您只想忽略具有特定扩展名的文件,则可以使用--exclude选项,例如--exclude=*.{jpg,jpeg}忽略所有以.jpg.jpeg结尾的文件。因此,你应该能够得到你想要的东西与此:

grep -r -l --binary-files=without-match . 

现在,你在你的意见,你的grep版本不具备-r-l选项之一提及。这是不幸的,我建议获得更新版本grep(最好是GNU品种)。

一名注:如果您使用find -exec,你应该使用+结束命令而不是semicoln,如:

find . -exec grep options '{}' '+' 

通过使用+find只会叉落单的过程,将所有匹配的文件名作为命令行参数传递给grep的一个实例。只要你没有一百万匹配的文件(这将创建一个比shell可以处理的命令行长得多的命令),这将会快得多。如果使用分号代替,find会为分配一个新进程,每个匹配文件,这对于大量文件来说确实很慢。

1
grep -r --exclude=*.jpg B206 . 

对不起,从另一个注释:

只有GNU的grep带有-r(递归),真正的UNIX的grep没有。你必须安装GNU grep或者在查找时使用它。 - 总站

1

用grep与发现,我的语法是:

find . -name "*" -print | xargs grep B206 

所有的选项来过滤文件,二进制和所有,然后将结果作为参数传递给grep命令传递。

1

我认为问题在于当你grep一个二进制文件时,它输出二进制数据。该二进制数据以某种方式在shell中得到解释。

我建议尝试使用命令“串”,使确保您的输出是纯文本的第一个,然后在输出用grep“弦”。

3

只是一个报价,你不需要关闭终端,你可以使用命令reset恢复端子输出模式。

你也可以做以前的grep命令来删除扩展你不想:

find -print | grep -v '\(\.jpg\|\.bmp\)$' | xargs grep "B206" 
2

鉴于最近lovefest超过ack,我很惊讶没有人提到它呢。

您可以通过扩展配置类型,以便'grep'只是你想要的文件。或者你可以使用--nobinary,鉴于你一直面临的问题。