如何列出文件名中包含“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中进行此测试没有非常方便的方法。