find 参数使用

今天遇到一个问题:就是要最近三天之内的file里的imgage 重新push 一次。
使用find  like this :
 for file in  `find log/ -mtime -3 |grep rdistI`
do
grep "$aa1.* updating" $file |.....
done
解释: log/ 表示在log/路径下寻找
           -mtime -3 : 今天之前3天之内
           grep :使用通道找到相关的名字的file

下面是find 的使用方法:

find最简单的应用,是搜索当前目录及其子目录下的文件。

$ find .
./tp1301.txt
./up1301.txt
./tp1302.txt
./up1302.txt
./Up1303.txt
./misc/uploads
./misc/uploads/patch12_13.diff

像往常一样,那个点(.)代表当前目录。在以上例子里,find列出了当前目录及其子目录下的所有文件。

如果只想搜索up开头的文件名,使用'-name'参数。

也就是如下命令:

$ find . -name up/*
./up1301.txt
./up1302.txt
./misc/uploads

find默认是大小写敏感的。如果想让find找到'p1303.txt'文件,要么使用'find -name UP/*',要么就用'iname'参数代替'name'参数。

通配符前的斜线是转义符,这样Bash才会把字面意义的星号传递给find作为参数,而不是首先把文件名扩展,再将扩展之后的那些文件名传递给find作为参数。

这个技巧很重要。要注意那些在shell里有特殊意义的字符。

我们也可以列出当前目录中以大小写不敏感的upup, Up, uP, UP)开头,其中非小写up的文件名。

$ find -iname up/* -not -name up/*

操作符

find使用-and-or,和-not参数支持布尔代数值。它们也可以分别缩写成-a-o!(在bash中必须使用/!进行转义)。或(and)操作符在此提及,只是内容完整的需要。它是默认就在使用的:

$ find . -iname david/*gray/*ogg -type f > david_gray.m3u

上例中的操作符将按如下顺序处理:

() 圆括号用圆括号强制执行顺序提前。

-not 反转测试表达式的结果。

-and ex1 -and ex2;如果第一个表达式为假,将不再执行第二个表达式。

-or ex1 -or ex2;如果第一个表达式为真,将不再执行第二个表达式。

',' 这是列表操作符(list operator)。不像-and-or,它将使两个表达式都执行。在'2 into 1 does go'部分有更多信息。

之前的那个例子将创建一个m3u播放列表,列出所有的以'David Gray'开头的ogg文件。(大小写不敏感)

$ find . -iname david/ gray/*ogg -type f > david_gray.m3u

这个例子则将找出所有叫"david gray...ogg"的文件,照样大小写不敏感。

下例在语义上与上例等同:

$ find . -iname david/ gray/*ogg -and -type f > david_gray.m3u

下例与上两例的语义等同:

$ find . -iname "david gray*ogg" -and -type f > david_gray.m3u





如果艺术家'David Gray'的名字有可能在文件名里,也有可能在子目录名里,怎样找到它们呢?
$ find . -ipath /*david/ gray/*ogg -type f > david_gray.m3u

表达式以星号通配符开头,因为可能有不止一个的叫'david gray'的子目录仅仅是为了分类的符号链接。(GNU find中此语句必须以/*开头,是因为不这样的话,就没有结果。并且-type f代表的是普通文件,-type l才是符号链接。所以,不知道作者说的什么意思。并且GNU find反对使用-ipath参数,应当使用的是-iwholename。)

这有另一个例子,我们将列出humour目录的内容(一行一个文件),然后搜索有大小写不敏感的'yodo'在文件名中的.mp3文件。

$ ls humour -1
Weird Al - Yoda.mp3
welcome_to_the_internet_helpdesk.mp3
werid al - livin' la vida yoda.mp3
 
 
  
   
 
 
$ find -ipath /*humour/*yoda/* -type f
./humour/Weird Al - Yoda.mp3
./humour/werid al - livin' la vida yoda.mp3

合并任务

在操作符一节就已经暗示了,可以用find一次执行多次任务。

下例创建两个列表文件,一个包括所有的.php文件,另一个包括所有.js文件。-fprint参数表示把搜索结果输出到文件中。

$ find ~ -type f /( -name /*.php -fprint php_files , -name /*.js -fprint javascript_files /)

剪切

假设您想创建一个播放列表文件列出所有David Gray.ogg文件,但是有些专辑你不想包括在内。

您可以用-prune参数阻止这些专辑出现在播放列表中,-prune参数匹配不包含某个表达式的目录或文件名。

下例能将FleshLost Songs专辑排除:

$ find /( -path ./mp3/David_Gray/Flesh/* -o -path "./mp3/David_Gray/Lost Songs" /* /) -prune -o -ipath /*david/ gray/*





首先,您会注意到被转义的圆括号,这样bash才不会误用它们。使用-prune参数,意思就是"别找这些,去找其他的"
$ find (-path <don't want this> -o -path <don't want this#2>)
/-prune -o -path <global expression for what I do want>

可能需要较长的时间才能掌握-prune参数的使用:首先要确定你究竟想使用它做什么。我发现使用-prune参数能省下不少时间让我去完成其他任务。

其他参数

还有许多其他表达式和参数可供find使用。

这有一些可能是您最想使用的:

-nouser 拥有文件的用户不在/etc/passwd文件中。

-nogroup 拥有文件的组不在/etc/groups文件中。

-owner <username> 指定用户拥有的文件。

我们将在稍后再研究这些参数以及其他一些参数的使用。

输出方式

改变输出信息

如果您输出的不仅仅是文件名,-printf参数可以输出任何种类你想要的信息。去看看手册页,那里有惊人多的选项。

以下这些可能是使用最多的:

%p 文件名,名字中包括其所在的目录,也即是路径名(path)。

%m 文件的权限,以数字显示。

%f 文件名,不包括所在目录。

%g 文件所属组名。

%h 显示文件所在目录。

%u 文件所属用户名。

如下例:

$ find . -name /*.ogg -printf %f/
 
 
  
   
 
 


将生成一个包含所有当前目录及其子目录想的.ogg文件列表。

' '前的反斜线很重要,' '代表开始新一行。'n'之前的反斜线必须被转义,否则命令行解释器将会首先使用' '

输出到哪里

find有一些参数控制输出信息写入到任何您想写入的文件。它们使-fprint-fprint0,-fprintf参数。

$ find . -iname david/ gray/*ogg -type f -fprint david_gray.m3u

这样,上例比下例更有效。

$ find . -iname david/ gray/*ogg -type f > david_gray.m3u

执行命令

文件是生成基本信息报告的很好工具,但是如果你想要的不仅仅是报告呢?你可以把标准输出用管道重定向给其他工具。

$ find ~/oggs/ -iname /*.mp3 | xargs rm

不过,这并不总是那么有效。

最好还是使用-exec参数。

$ find ~/oggs/ -iname /*.mp3 -exec rm {} /;

也许这个例子比较难看懂,它的意思是搜索到这些文件后便立即将其删除。

'{}'是一个代表找到的所有文件的占位符,';'必须被转义,以免bash误用。

谨慎起见,-ok参数可以代替-exec-ok参数会在执行命令之前请就确认。

这有许多种方法可以用到日常真实情况中。

比如,你的默认Mozilla配置文件被锁定了,下例可以帮你解锁。(删除lock文件即可)

$ find ~/.mozilla -name lock -exec rm {} /;

压缩当前及其子目录下所有日志文件:

$ find . -name /*.log -exec bzip {} /;

将当前及其子目录下所有无有效用户权限的文件的权限赋予给用户ken

$ find . -nouser -exec chown ken {} /;

vim打开所有当前目录下的.dat文件,不搜索子目录。

$ vim -R `find . -name /*.dat -maxdepth 1`

在当前目录中至少四层以下(包括四层)的子目录中搜索目录名CVS

$ find -mindepth 4 -type d -name CVS

创建时间

也许您想搜索最近创建的文件,或者查找近三天内的日志文件中的字符串。

这是find所擅长的:它可以根据文件的时间戳来限制搜索的范围。

假设您想找到您主目录中近五天内修改过的隐藏文件:

$ find ~ -mtime -5 -name /./*
  
  

如果你知道某个文件在更近的时间内修改过,例如14分钟内,可用如下参数:

$ find ~ -mmin -14 -name /./*
  
  

注意,列出文件(ls)的操作会影响文件的访问时间戳。如果你先做一次列出文件(ls)的操作,然后再使用上例中的命令,所有的文件都会列出。(不知道作者用的是什么版本的findGNU find 4.32是区别aminaccess)和mminmodify)的,上例仍有效)

找到那些在某个时间点之后修改过的文件,可以使用下例中的技巧:

$ touch -d "13 may 2001 
 
 
  
  17:54:19
 
 " date_marker



$ find . -newer date_marker
  
  

找到创建于上例中时间点之前的文件,使用'cnewer'加否定式:

$ find . /! -cnewer date_marker
  
  

找出昨天里修改过的文件:

$ find . -daystart -atime 1 -maxdepth
  
  

'-daystart'参数意思是时间从今天的开端(也即今日之零点)开始计算,而不是从当前时间点开始计算。

这个参数只对'-amin''-atime''-cmin''ctime''mmin''mtime'选项有效。

文件大小

字符文件

要找出有含有指定数量字符的文件,您能错过这节。

找出有正好有1000个字符的文件:

$ find . -size 1000c
  
  

找出有600700个字符的文件,600700包含在内:

$ find . -size +599c -and -size -701c
  
  

字符(character)其实是误称:'c'find中是字节(byte)意思;所以这些命令只能作用于ASII文件,对Unicode文件无用。

参考用户手册,我们可以看到:

c = 字节 bytes w = 2字节 2 byte words k = 千字节 kilobytes b = 512字节的块 512-byte blocks

这样我们可以用find来找出指定大小的文件:

$ find /usr/bin -size 48k
空文件

你可以用下例找到空文件:

$ find . -size 0c
  
  

-empty参数更有效。

删除当前目录下所有空文件:

$ find . -empty -maxdepth 1 -exec rm {} /;

用户和组

用户

搜索属于指定用户的文件:

# find /etc -type f /!  -user root -exec ls -l {} /;
-rw------- 1 lp sys 19731 2002-08-23 
 
 
  
  15:04
 
  /etc/cups/cupsd.conf
-rw------- 1 lp sys    97 2002-07-26 
 
 
  
  23:38
 
  /etc/cups/printers.conf

如果只需要上面列出信息的子集的话,就没必要使用exec

root@ttyp0[etc]# find /etc -type f /!  -user root -printf "%h/%f %u/"
/etc/cups/cupsd.conf lp
/etc/cups/printers.conf lp

如果您只知道用户iduid),而不知道用户名的话,可以用'-uid'参数:

$ find /usr/local/htdocs/www.linux.ie/ -uid 401

'-nouser'参数意思是所有在/etc/passwd文件中的用户都不拥有所要搜索的文件。

也可以搜索属于或不属于指定组的文件,取决您如何使用它。

这非常适合用来搜索那些本该属于www组,但却不属于的文件:

$ find /www/ilug/htdocs/  -type f /! -group  www

'-nogroup'参数意思是所有在/etc/group文件中的组都不拥有所要搜索的文件。

如果某个组使用过一段时间后被删除了,这个参数就有用了。

'gid'参数搜索属于指定gid的文件。

$ find -gid 100

权限

如果您曾经因为权限设置问题而无法运行一些脚本,并且您想一次性解决这个问题,那您应该看下面这个小例子:

knoppix@ttyp1[bin]$ ls -l ~/bin/
total 8
-rwxr-xr-x    1 knoppix  knoppix        21 2004-01-20 
 
 
  
  21:42
 
  wl
-rw-r--r--    1 knoppix  knoppix        21 2004-01-20 
 
 
  
  21:47
 
  ww
knoppix@ttyp1[bin]$ find ~/bin/ -maxdepth 1 -perm 644 -type f -not -name ./*
/home/knoppix/bin/ww

找出所有没有执行权限(644)的文件,就像我们在输出中看到的。

文件类型

'-type'参数明显是用来指定寻找什么类型的文件的(记住,在Linux下,一切东西都是某种文件)。

目前为止,我用过'-type f'来寻找普通文件。

如果我们想找到'_of_'在其文件名中的目录,可以用:

$ find . -type d -name '*_of_*'

上例中的输出不会包括指向目录的符号链接。

如果想包括目录和指向目录的符号链接,请用:

$ find . /( -type d -or -type l /) -name '*_of_*'


参考用户手册,以获得所有文件类型的完成列表。

正则表达式

我们已经偶尔使用过通配符来指定一组文件。find也支持正则表达式,所以我们也可以使用更复杂的规则来指定要搜索的文件。正则表达式会以整个路径为匹配对象:

ken@gemmell:/home/library/src$ find . -regex '.*/mp[0-4].*'
./library/sql/mp3_genre_types.sql

'-regex'的大小写不敏感的形式是'-iregex'

使用正则表达式的技巧是:注意匹配的是文件的绝对路径,即使是在搜索当前文件文件夹。如:

$ cd /usr/share/doc/samba-doc/htmldocs/using_samba
$ find . -regex './ch0[1-2]_0[1-3].*'
./ch01_01.html
./ch01_02.html
./ch02_01.html
./ch02_02.html
./ch02_03.html

文件系统

使用root用户将一个微软格式的软盘挂载起来做一个实验:

$ su -
# mount /floppy
# mount
/dev/sda2 on / type ext2 (rw,errors=remount-ro)
proc on /proc type proc (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
/dev/fd0 on /floppy type msdos (rw,noexec,nosuid,nodev)

然后试如下命令:

$ find / -fstype msdos -maxdepth 1

您应该只看到/floppy列出来。

要得到想反的结果,比如列出不在msdos文件系统上的文件,可用:

$ find / -maxdepth 1 /( -fstype msdos /) -prune -or -print

这只是对指定文件系统来搜索文件的一个简单介绍。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值