请教关于find查询的问题

sh/bash/dash/ksh/zsh等Shell脚本
回复
头像
shinery
帖子: 1378
注册时间: 2009-07-22 22:23

请教关于find查询的问题

#1

帖子 shinery » 2014-10-05 19:58

今天遇到一个问题,举例如下:
在bash下:

代码: 全选

find . > 1.txt
然后打开1.txt,你会发现1.txt这个文件中包含了1.txt它本身的路径记录。由于要用到1.txt中的行统计功能,所以用cat命令就不行了,改用sed可以屏蔽1.txt的记录行。但是为什么会这样?

然后换一个方法:

代码: 全选

find . -exec echo {} > 1.txt \;
据网上解释,find 会一次性把搜索结果传递给 exec 执行,如果是这样的话,在find完事之前,1.txt是不存在的,那么在1.txt文本中不应该包括1.txt本身的路径记录,但是你打开看一下,1.txt的记录依然存在,为什么是这样呢?
愿扣上你双手,至繁华浪处到沙丘。
cao627
帖子: 992
注册时间: 2007-12-05 10:57
系统: ubuntu14.04
来自: 金山

Re: 请教关于find查询的问题

#2

帖子 cao627 » 2014-10-05 20:56

代码: 全选

$ echo  "`find .`"  > 1.txt
头像
astolia
论坛版主
帖子: 6703
注册时间: 2008-09-18 13:11

Re: 请教关于find查询的问题

#3

帖子 astolia » 2014-10-06 12:12

第一个问题,涉及到shell对重定向的实现。bash的重定向是,有可能先创建1.txt,再执行find .,也有可能先执行完了find .,再创建了1.txt,还有可能find执行到一半的途中创建了1.txt。所以具体输出中有没有1.txt实际上是不能确定的
一些底层细节问题可以看此篇讨论 http://forum.ubuntu.com.cn/viewtopic.ph ... &p=3076341

第二个问题,我不知道你是从哪里看来的解释,这种情况下最好查manpage
http://manpages.ubuntu.com/manpages/tru ... ind.1.html
-exec command ;
Execute command; true if 0 status is returned. All following
arguments to find are taken to be arguments to the command until
an argument consisting of `;' is encountered. The string `{}'
is replaced by the current file name being processed
everywhere
it occurs in the arguments to the command, not just in arguments
where it is alone, as in some versions of find. Both of these
constructions might need to be escaped (with a `\') or quoted to
protect them from expansion by the shell. See the EXAMPLES
section for examples of the use of the -exec option. The
specified command is run once for each matched file. The
command is executed in the starting directory. There are
unavoidable security problems surrounding use of the -exec
action; you should use the -execdir option instead.
里面可没有说什么一次性把结果全部交给command,相反红字部分还专门说明了是逐个文件处理的
不过你的问题实际和这个无关。

代码: 全选

find . -exec echo {} > 1.txt \;
实际上还是

代码: 全选

find . -exec echo {} \;  > 1.txt 
因为重定向不一定要放在末尾。你可以自己试试

代码: 全选

echo "123" >1.txt "234"
>2.txt echo "123"
另外-exec后面的command是程序,不是shell命令,所以不能直接用shell的功能如管道、重定向、直接操作环境变量等

-exec有个变种可以在manpage里查到
-exec command {} +
This variant of the -exec action runs the specified command on
the selected files, but the command line is built by appending
each selected file name at the end
; the total number of
invocations of the command will be much less than the number of
matched files. The command line is built in much the same way
that xargs builds its command lines. Only one instance of `{}'
is allowed within the command. The command is executed in the
starting directory.
这个倒是可以把多个结果(不一定是全部,视文件名总长度和find内部缓冲区大小而定)一次性传给command,不过这种写法本身限制太多,一般不怎么用

代码: 全选

find -exec bash -c '> 1.txt' echo {} +
回复