如何列出文件名中包含“2015”的文件超过一天的文件?
我想列出所有不属于今天的日志文件,只列出名称中包含2015
的文件。
这些是我尝试过的命令:
find . -name 2015 -mtime +1 -exec ls -ltrh {} \;
find . -name *2015* -mtime +1 -exec ls -ltrh {} \;
两者的输出都没有,但仍然存在文件。 这些命令有问题,我没有得到什么。 任何帮助,将不胜感激。
命令find . -name '*2015*' -mmin +1440 -ls
find . -name '*2015*' -mmin +1440 -ls
可能会做你想要的。 请参阅下文了解详情。
你的第一个命令有-name 2015
。 它不起作用,因为它只找到名称正好是 2015
文件,其中没有其他字符。
你的第二个命令, find . -name *2015* -mtime +1 -exec ls -ltrh {} \;
find . -name *2015* -mtime +1 -exec ls -ltrh {} \;
,可能因为以下几个原因而失败:
1.未加引号的*
字符由shell扩展, 然后传递给find
。
如果当前目录中直接包含任何文件(运行find ...
命令时所在的目录),其名称包含2015
(并且不以.
开头),那么shell展开了*2015*
进入这些文件名的列表,然后将该列表作为参数传递给find
。 这不是你想要的 – 相反,你希望将*2015*
字面上作为参数传递给find,这样find
,而不是shell,可以找到与之匹配的文件。
要解决这个问题,请引用*2015*
。 有三种常用方法:
-
'*2015*'
(即find . -name '*2015*' -mtime +1 -exec ls -ltrh {} \;
) -
"*2015*"
(即find . -name "*2015*" -mtime +1 -exec ls -ltrh {} \;
) -
\*2015\*
(即find . -name \*2015\* -mtime +1 -exec ls -ltrh {} \;
)
我建议 用单引号将其写成'*2015*'
,因为:
- 使用
\
引用单个字符可能会很难确切地看到shell将哪些字符传递给find
命令。 - 引用
"
有时涉及一些复杂的规则 。
但在这种情况下,它并不重要。 '
和"
都对待*
相同而且表达式不够复杂,不能用于引用以使其难以理解。
2. -mtime +1
仅选择两天或两天以前修改过的文件。
正如man find
那样:
Numeric arguments can be specified as +n for greater than n , -n for less than n , n for exactly n .
-mtime n File's data was last modified n*24 hours ago. See the comments for -atime to understand how rounding affects the interpretation of file modification times.
-atime n File was last accessed n *24 hours ago. When find figures out how many 24-hour periods ago the file was last accessed, any fractional part is ignored, so to match -atime +1 , a file has to have been accessed at least two days ago.
假设一个文件在47小时前被修改过。 要弄清楚有多少24小时的时间段,请find
四舍五入:它是一个 24小时前的时间段。 但是-mtime +1
仅匹配修改时间严格超过 24小时前的文件。 因此昨天的文件不匹配。
请参阅为什么发现-mtime +1仅返回超过2天的文件? 有关更多信息,请参阅steeldriver的建议 。
要在超过24小时之前的任何时间查找上次修改的文件,我建议使用-mmin +1440
其规定为1440分钟前 :
find . -name '*2015*' -mmin +1440 -exec ls -ltrh {} \;
有些读者可能想知道为什么我没有引用{}
。 有些人引用{}
来提醒人类,这不是支撑扩张的表达。 Bourne样式的shell (比如bash )不需要{}
,内部没有任何内容可以引用。 也许一些非Bourne风格的shell确实特别对待它; 这可能是一些用户引用它的原因。 但是也有一种误解 ,即有时必须引用{}
所以-exec
正确处理带空格的文件名。 那; s; false:使用{}
或'{}'
, find
获取相同的参数,因为shell在传递'{}'
之前删除了引号 。 为了克服这种误解,我不引用{}
,但这是一个风格问题 – 如果你更喜欢{}
来记录shell如何不特别处理{
和}
,那很好。
我建议你也改变你的ls
命令,或者(正如muru建议的那样 )用find
的-ls
动作替换它。 ls -ltrh
可能没有按你的意愿行事,因为它是针对找到的每个文件单独运行的,因此指定排序的-t
和-r
标志是无关紧要的。
虽然输出的格式与ls -l
格式有点不同,但使用-ls
更简单,更容易。
find . -name '*2015*' -mmin +1440 -ls
或者,如果您确定只需要列出文件的名称(包括它们的路径,相对于.
),您可以简单地指定无操作,从而导致使用默认的-print
操作:
find . -name '*2015*' -mmin +1440
引用表达式,我建议你引用括号
find . -name "2015" -mtime +1 -exec ls -ltrh '{}' \;
要么
find . -name "*2015*" -mtime +1 -exec ls -ltrh '{}' \;
你不需要将你找到的文件传递给ls
find . -name "*2015*" -mtime +1
在zsh中 ,您可以使用glob限定符 (这是一个独特的zshfunction,在其他shell中不可用,例如bash)。
ls -ltr *2015*(m+1)
这只列出当前目录中的文件; 要递归遍历目录 ,请使用
ls -ltr **/*2015*(m+1)
使用find
, -name 2015
仅查找名称正好为2015
文件。 -name *2015*
仅在当前目录中没有名称包含2015
文件时才有效,因为shell会在调用find
之前扩展模式*2015*
。 你需要引用模式:
find -name '*2015*' -mtime +1 …
请注意, find -mtime +1
和zsh的*(m+1)
查找至少48小时的文件,而不是今天比较早的文件。 加号表示“严格超过”,并且天数向下舍入。 要查找至少24小时的文件,请使用-mtime +0
或(m+0)
。
如果要查找昨天或之前修改过的文件,可以将find
与-newermt
谓词一起使用 :
find -name '*2015*' ! -newermt 'today 0:00' …
在zsh中进行此测试没有非常方便的方法。