find & grep 总 结

find & grep 总 结

前言

关于本文

总 结 了 find、grep常 规 用 法,正 则 表 达 式,find与 grep合 用 以 及 自 定 义 搜 索 函 数 等

什么是find和grep

find 和 grep 是 linux中 最 常 用 的 两 个 搜 索 函 数,本 文 将 会 介 绍 并 例 示 这 两 个 函 数 的 用 法。

为什么要用find和grep

对 其 的 熟 练 掌 握 可 以 明 显 提 高 搜 索 效 率,尤 其 是 面 对 动 辄 几 十 G 源 码 时 。

关 于 参 数

find和grep有很多参数,可以用以下命令导出查看:

man grep > grep.txt

man find > find.txt

参数可以帮助我们在使用时提高效率,实现特定需求以及避免错误,本文会介绍一些常用参数。

两者的区别,用find还是用grep

关于用find还是用grep,只要掌握一个原则就可以了:

凡是搜索文件名,就用find

凡是搜索文件内容,就要grep(当然为了提高效率可以结合find使用,后面会讲)

find基本用法

搜索文件名

例:在当前目录搜索名称为DialactsActivity.java的文件

find ./ –name DialactsActivity.java

参数 –a  –o  –not

分别为与、或、非的意思,相当于find中的逻辑运算

例1:在当前目录搜索除了AndroidManifest.xml文件以外其他的xml文件

find ./ –not –name AndroidManifest.xml –a –name “*.xml”

例2:在当前目录搜索名称为values-zh-rCN或values的文件

find ./ -name values-zh-rCN -o -name values

参数 –prune

该参数的作用是忽略某个文件,即不在这个文件夹里搜索文件以提高效率,该参数常和-o一起使用

例1:在当前目录且不在res文件中搜索名为values-zh*的文件并打印

find ./ -name res -prune -o -name values-zh* -print

Note最后的-print,如果不加-print结果中除了打印不在res文件中的values-zh*文件之外还会打印find . -name res这个搜索出来的结果

tips*为通配符

参数 –exec

find命令后加入该参数可以对搜索结果进行处理

例:在当前目录搜索所有java文件并将其删除

find ./ –name “*.java” –exec rm –rf {} \;

Note{} 表示前面搜索的结果, “; ”表示命令结束, “ \ ”用于转义且前面必须要有空格

参数 –type

该参数用于指定查找文件的类型

例1:在当前目录查找文件名包含res的文件夹

find ./ –name “*res*” –type d

-type参数后跟指定的文件类型,d为文件夹,f为普通文件

参数 –size

用于指定查找文件的大小(单位b、k、M、G)

例1:在当前目录查找所有小于10k的文件

find ./ –size -10k

例2:在当前目录查找所有大于10M的文件

find ./ –size +10M

find搜索匹配进阶及RE(正则表达式)

-name

-name 是将文件名去匹配而不是文件的输出结果

*      :代表任意字符(可以没有字符)

?   :代表任意单个字符

[]       : 代表括号内的任意字符,[abc]可以匹配a\b\c某个字符

[a-z] :可以匹配a-z的某个字母

[A-Z]:可以匹配A-Z的某个字符

[0-9]:可以匹配0-9的某个数字

如果方括号内加入“ ^ ”,则表示不去匹配里面的字符

[^a-z]:表示不匹配a-z的某个字符。

例1:在当前目录中搜素不以a、b、c开头的所有文件

find ./ –name “[^abc]*”

例2:在当前目录中搜索以大写字母或数字开头的所有文件

find ./ -name “[A-Z0-9]*”

-regex

-regex是将文件的输出结果进行匹配而不是文件名

比如,当前目录中有a文件夹,a中有b文件夹,b中有c文件

那c文件的文件名为c,输出结果为./a/b/c,前者用于-name匹配,后者用于-regex匹配

-regex相对于-name的优势是可以使用正规的RE

例:搜索所有输出结果包含res的文件(哪怕文件名不包含res,只要该文件在res文件夹中也都可以被搜索到)

find . –regex “.*res.*”

Note这里匹配所有字符是 .* 而不是 *

简单的RE符号及用法

[]     : 与之前find中描述相同,在此不予赘述

.        : 表示任意单个字符

?  : 表示前面的字符出现一次或零次

+       : 表示前面的字符至少出现一次

*       : 表示前面的字符出现零次或多次

()       :将表示的字符括起来后面跟量词

例:在当前目录搜索输出结果至少出现一次res的所有文件

find ./ -regex “.*\(res\)+.*”

Note()要用\转义,该例将会打印出所有包含res的目录及其中的文件

|       : 逻辑或,可以搜索两个条件

例:在当前目录搜索所有文件名末尾为res或res_ext的文件

find ./ -regex “.*res|.*res_ext”

grep基本用法

先用两个例子看grep最简单的用法

例1:在Android.mk文件中搜索包含res的行

grep “res” Android.mk

例2:在当前目录的所有文件中搜索包含res的行

grep “res” ./*

参数 –r

表示在当前目录和子目录中循环搜索(加入该参数可以不用指定文件,意为已经指定了当前目录及子目录中的所有文件)

例:在当前目录及子目录中的所有文件中搜索包含res的行

grep –r “res”

参数 –n

输出的结果打印行号

例:在当前目录及子目录中的所有文件中搜索包含res的行并打印行号

grep –nr “res”

参数 –i

查找匹配忽略大小写,默认状态下会匹配大小写

参数 –l(L的小写,不是大写的i)

输出结果只显示文件名,不显示行

参数 -s

不显示不存在或无匹配文件的错误信息

参数 –w

可以精确匹配后面的单词,而不是字符串匹配

参数 -v

逆反模式,即输出不匹配的所有行

grep中RE的使用以及egrep

find中所说的REgrep这边都可以使用,后面不再赘述,需要注意的是 + 、?要用\转义

什么是egrep

egrep是grep的进化版,改进了许多grep中不方便之处如下:

egrep使用RE符号 + , ? , | (或) , {} 时不用转义,如果要用其本身则需要/转义

所以,如果需要用到RE的话,尽量选择egrep

简单的RE符号及用法

\< , \>       :分别表示单词的开始和结束,将单词放入其中可以精确匹配(类似于-w)

例:搜索精确匹配Dialer单词的行(形如DialerActivity则不会匹配)

egrep –nr “\<Dialer\>”

Note \>表示的是单词的结束,单词可能是下一个单词,这里写的时候需要注意

^ , $           : 分别表示行的开始和结束(^ 用在 [ ] 内表示不匹配其中的字符,注意区别)

{n}              : 表示前面的字符匹配n次

{n,m}          : 表示前面的字符匹配n-m次

{,m}           : 表示前面的字符至多匹配的m次

{n,}            : 表示前面的字符至少匹配n次

[ ]                : 方括号使用和find一样,也可以使用国际模式,但感觉不如直接写形如[0-9a-zA-Z]易于理解,因此不予展开

[[:space:]]:表示空格或tab

例1:当前目录搜索包含access your和Phone permission的行(如果中间的字符串看不清或者不方便写或者可能是转义符如换行符等,可以用.*代替)

egrep –nr “access your.*Phone permission”

findgrep的在搜索中的实际应用-进阶

前面说了这么多,其实都是在为这一小节做铺垫,相信在实际应用中大家不会在源码中直接去grep搜索,这样会相当耗时,因此,我们需要掌握一些技巧以使搜索变得简单而又高效:

find和grep结合使用

在实际应用中,find和grep配合使用将会非常方便而迅速,先看一个例子:

function jgrep()
{
    find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.java" -print0 | xargs -0 grep --color -n "[email protected]"
}

这个是位于Android源码build/envsetup.sh中的jgrep函数,用于搜索java文件内容,是经常使用的一个函数,是find结合grep的典型案例。如果已经确定了搜索内容在java文件中,那么相比于直接用grep进行全局搜索,这种先搜索所有的java文件,再在其中搜索内容的方式可以显著提高效率。

我们先来解析一下这个函数:

find .         :在当前目录搜索

-o                : 或,并列多个条件

-name .repo –prune         : 忽略.repo目录(git库相关)

-name .git –prune             : 忽略.git目录(git库相关)

-name out –prune             : 忽略out目录(编译生成的目录)

-type f      :指定文件类型为普通文件

-name "*\.java"       : 指定匹配的文件名为.java文件

-print0 | xargs -0      : 忽略搜索中可能出现的错误信息,并将搜索到的文件作为结果向后传递并继续执行

grep --color –n :用grep在之前搜索到的文件中进行内容搜索,输出行号并标识颜色

"[email protected]"        :表示在使用jgrep函数时输入的参数,这里即为grep搜索的内容(本人未搞清这里为什么写[email protected]而不是$*、$1)

这么分析下来,这个函数的意思应该很容易就可以理解了,在这个基础上,大家可以根据实际情况举一反三,以写出适合自己的函数或者命令。

find、grep中xargs 和 | 的使用

|       :管道命令符,它会将前一个命令的标准输出作为后一个命令的标准输入,这里不展开了,具体作用可以自行寻找资料学习。

xargs 如果仅使用 | ,那么前面的结果会作为输入直接传递到后面的命令中,而使用xargs,就可以使前面的结果作为参数传递到后面的命令中,而这个特性对于find和grep而言十分重要。下面举几个例子来说明find中xargs的用法:

例1:在当前目录中搜索所有AndroidManifest.xml文件并在其中搜索DialtactsActivity

find . –name AndroidManifest.xml | xargs grep –n –color “DialtactsActivity”

说明:该例是xargs最基本的用法,如果将xargs去掉,那么grep搜索的内容是find输出的结果内容而非结果文件

例2:在当前目录搜索所有的values-zh-rCN文件目录并在其中搜索所有的strings.xml文件(即所有中文字符串存放位置),然后在搜索到的strings.xml文件中搜索“通话”字符串

find . –type d –name “values-zh-rCN” | xargs –i find {} –name “strings.xml” | xargs grep –n –-color 通话

tips该例中xargs后使用了-i参数,该参数的作用是可以将后面命令中的 {} 符号视为前面find搜索的结果文件。本例中连续使用了两次xargs进行结果的传递。

例3:在当前目录中的所有mk文件中搜索ro.build.type

find . –type f –name “*.mk” –print0 | xargs -0 grep –n –color “ro.build.type”

tips本例中和之前提到的jgrep函数都是用了 –print0 | xargs -0进行结果传递而非单纯使用xargs,这样做的好处是如果find搜索会忽略可能出现的错误,使最终输出的结果更清晰,因此在使用xargs时建议按照–print0 | xargs -0方式写命令。

编写搜索函数

学习find和grep的使用是为了使用方便和提高效率,如果每次搜索都和上面的例子那样敲一堆命令,虽然提高了效率,方便和使用性上却大打折扣,因此,我们需要将命令进行抽象,编写搜索函数,就如同之前所讲的系统自带的jgrep函数一样,做到真正的实用而又高效。

为了更加直观,举一个例子来说明如何编写搜索函数,这里需要用到一些简单的编写shell脚本基础知识:

#文件内容搜索函数sep

#参数1 必选 搜索内容

#参数2 可选 前缀-t 内容所在的文件类型(即文件后缀名,如java),缺省为所有文件类型

#参数3 可选 前缀-f 指定搜索的目录 缺省为当前目录及所有子目录

#用例 sep "new ITelecomService.Stub"  -t  java xml  –f  packages/ frameworks/

#用例解析 在packages、frameworks目录中的所有java、xml文件中搜索"new ITelecomService.Stub"

function sep()
{

#文件内容=第一个参数

se_content=$1

#文件类型和搜索目录暂时=空

se_fileType=""
se_folder=""

#shift的作用是将第一个参数移除,即当前函数输入的第二个参数变成第一个参数,第三个变成第二个,以此类推

shift

#判断当前第一个参数是否为-t,即文件类型是否指定,如果指定就取出文件类型放入se_fileType变量中

if [ "$1" = "-t" ];then
    #如果是-t就将这个参数移除
    shift
    while ( [ "$1" != "-f" ] && [ -n "$1" ] )
    do
        se_fileType="$se_fileType $1"
        shift
    done
fi

#判断当前第一个参数是否为-f,即搜索目录是否指定,如果指定就取出搜索目录放入se_folder变量中

if [ "$1" = "-f" ];then
    #如果是-f就将这个参数移除
    shift
    while [ -n "$1" ]
    do
        se_folder="$se_folder $1"
        shift
    done
fi

#判断文件类型是否为空,不为空则建立循环分别搜索指定的文件类型

if [ -z $se_fileType ];then
    #这里如果搜索目录为空find会自动搜索当前目录及子目录,因此不用再做判断
         #这里用到了egrep而不是grep,方便输入搜索内容时直接使用正则表达式
    find $se_folder -type f -print0 | xargs -0 egrep -n --color "$se_content"
else
    for ft in $se_fileType
    do
        find $se_folder -type f -name "*.$ft" -print0 | xargs -0 egrep -n --color "$se_content"
    done
fi
}

这个函数整体而言比较简单,加上其中的注释,想必大家可以很容易理解,在这个基础之上我们还可以添加其他参数,比如是否精确匹配等,这里不再具体说明了。

关于函数如何使用:写到.sh文件中再用source命令导入即可在命令行直接使用,这是linux中最基本的操作,不太明白的同学可自行百度。

tips:也可以仿照前面说的jgrep函数编写简单的函数如下:

function mkgrep()
{
    find . -name .repo -prune -o -name .git -prune -o -name out -prune -o -type f -name "*\.mk" -print0 | xargs -0 grep --color -n "[email protected]"
}

只是把java改成mk就可以直接搜索所有mk文件,实用性也很强。

原文地址:http://blog.51cto.com/haowen/2068456

时间: 2024-08-02 12:45:48

find & grep 总 结的相关文章

转 A?B?A?P?_?E?x?c?e?l? ?处?理?总?结

gui_download怎么下载复杂的ALV表头为EXCEL http://blog.csdn.net/iamah/article/details/7497309 ABAP EXCEL文件上传与下载 http://blog.csdn.net/yuqinying112/article/details/7557805 A?B?A?P?_?E?x?c?e?l? ?处?理?总?结 http://wenku.baidu.com/link?url=-vgXjbL8OH1E38dYCVx6avGp5mFMsM

W?o?r?d?P?r?e?s?s?常?用?标?签?和?调?用?总?结

调用头部模板<?php get_header();?> 调用尾部模板<?php get_footer();?> 调用侧边栏<?php get_sidebar();?> 放在head标签内,方便插件调用:<?php wp_head(); ?> 放在footer里,body结束之前,方便插件调用:<?php wp_footer(); ?> --------------------------------------------------------

android WebView总 结

浏览器控件是每个开发环境都具备的,这为马甲神功提供了用武之地,windows的有webbrowser,android和ios都有webview.只是其引擎不同,相对于微软的webbrowser,android及ios的webview的引擎都是webkit,对Html5提供支持.本篇主要介绍android的webview之强大. A.    webview组件如何使用 1)       添加权限:AndroidManifest.xml中必须使用许可"android.permission.INTER

SVN 总 结 一

一.svn是什么? SVN是Subversion的简称,是一个开放源代码的版本控制系统,在它的管理下,文件 和目录可以超越时空的限制,权且当作一种神奇的"时间机器".通俗的说,SVN就是一 个便捷的合作开发项目的跨平台软件.有了svn我们可以跨时空的进行项目的合作开发, 不在受空间一定要在一起或同一个地点面对面进行项目开发. svn(subversion)是近年来崛起的版本管理工具,是cvs的接班人.目前,绝大多数开源 软件都使用svn作为代码版本管理软件. 二.工作流程: 开始新一天

java程序

This XML file does not appear to have any style information associated with it. The document tree is shown below.博客园_首页代码改变世界uuid:5de59c50-a92f-4447-96ed-ab86451ed183;id=61182014-07-27T11:59:08Zfeed.cnblogs.comhttp://www.cnblogs.com/jianyus/p/3865670

实用干货丨如何使用Prometheus配置自定义告警规则

前 言 Prometheus是一个用于监控和告警的开源系统.一开始由Soundcloud开发,后来在2016年,它迁移到CNCF并且称为Kubernetes之后最流行的项目之一.从整个Linux服务器到stand-alone web服务器.数据库服务或一个单独的进程,它都能监控.在Prometheus术语中,它所监控的事物称为目标(Target).每个目标单元被称为指标(metric).它以设置好的时间间隔通过http抓取目标,以收集指标并将数据放置在其时序数据库(Time Series Dat

SharePoint Online 创建门户网站系列之图片滚动

?? 前 言 创建SharePoint Online栏目我们之前已经介绍过了,具体就是内容编辑器方式.自带WebPart方式和JavaScript读取后台数据前台做展示的三种: 但是,对于复杂的展示来说,这些方式还是会比较难以实现,虽然对于首页的图片轮播来说,通过JavaScript方式已经完全能够胜任,但是,我还是想通过这个栏目,为大家介绍如何使用沙盒解决方案创建WebPart,来完成更加复杂的前台展示. 下面,让我们开始在SharePoint Online的门户网站中创建沙盒解决方案吧 .

SharePoint 2013 操作文档库ECB菜单

在SharePoint的使用中,我们经常需要定制SharePoint的一系列菜单,这里就包括ECB菜单,下面,我们简单了解一下ECB菜单如何定制,以及原理. 1.正常情况文档库的ECB菜单如下图: 2.我们首先复制如下js,然后在页面上添加引用 <script src="/_layouts/15/CORE2.JS" type="text/javascript"></script> 3.隐藏查看/编辑属性: 效果如下图: 4.隐藏工作流 效果如

Office 365 - SharePoint 2013 Online之应用程序开发工具

1.新建一个网站集,模板选择开发人员模板,如下图: 2.确定以后,需要稍等一会儿; 3.点击网站内容,添加app,如下图: 4.进入SharePoint Store,选择Napa,如下图: 5.选择ADD IT,如下图: 6.可能需要登录,如果没有微软账号,可以注册一个,如下图: 7.点击继续,如下图: 8.Return to site,如下图: 9.点击信任他,如下图: 10.稍等片刻,就添加成功了,如下图: 11.点击进入Napa,可以在这里创建app,如下图: 总 结 试用了一下Napa,