【问题标题】:unix command to find most recent directory created用于查找最近创建的目录的 unix 命令
【发布时间】:2011-07-27 03:21:59
【问题描述】:

我想从最近创建的目录中复制文件。我将如何在 unix 中这样做?

例如,如果我将目录名称作为日期戳:

/20110311
/20110318
/20110325

【问题讨论】:

  • 创建时间不存储在 Unix 中。您必须适应上次修改的时间。
  • 最后修改时间是我想要的目录。我怎么得到它?我会为此使用find 吗?
  • 任何时候将文件添加到目录中,都会更新目录的最后修改时间。可以吗?
  • 而且,您的目录是否总是根据 YYYYMMDD 日期模式命名?因为这将使解决方案更容易。 :-) 不过,如果一天内创建了多个目录,不知道如何应对!
  • @Juilus - 是的,我使用 YYYYMMDD 日期作为我的模式。

标签: shell unix find unix-timestamp


【解决方案1】:
lastdir=`ls -tr <parentdir> | tail -1`

我不知道如何让反引号与这里的评论系统配合得很好。只需将这些撇号替换为反引号即可。

【讨论】:

  • 在 bash 中,您可以使用 $(...) 代替反引号。
【解决方案2】:

经过一些实验,我想出了以下几点:

unix stat 命令在这里很有用。 '-t' 选项导致 stat 以简洁模式打印其输出(全部在一行中),并且该简洁输出的第 13 个元素是最后一个的 unix 时间戳(自纪元以来的秒数)-修改时间。此命令将按从最新修改到最旧修改的顺序列出所有目录(和子目录):

find -type d -exec stat -t {} \; | sort -r -n -k 13,13

希望 stat 的“简洁”模式将在 stat 的未来版本中保持一致!

下面是对所使用的命令行选项的一些解释:

find -type d                # only find directories
find -exec [command] {} \;  # execute given command against each *found* file.
sort -r                     # reverse the sort
sort -n                     # numeric sort (100 should not appear before 2!)
sort -k M,N                 # only sort the line using elements M through N.

回到你原来的请求,复制文件,也许试试下面的。要仅输出单个目录(最近),请将其附加到命令中(注意初始管道),然后将其全部输入到带有反引号的“cp”命令中。

| head --lines=1 | sed 's/\ .*$//'

【讨论】:

  • 感谢您的建议。很有意思。您可以编辑它以便我可以看到整个命令吗?我不确定我是否尝试正确。再次感谢。
【解决方案3】:

这就是我认为您要问的问题的答案。

当我处理名称中包含日期/时间戳的许多目录时,我总是采用您所拥有的方法,即 YYYYMMDD - 这样做的好处是日期顺序是也是字母顺序。在大多数 shell(当然在 bash 中,我对其他 shell 有 90% 的把握)中,'*' 扩展是按字母顺序完成的,默认情况下,'ls' 返回字母顺序。因此

    ls | head -1
    ls | tail -1

给你目录中最早和最晚的日期。

这可以扩展为仅保留最后 5 个条目等。

【讨论】:

  • 这基本上就是我所需要的。谢谢!
  • 实际上,如果我确实需要创建前 2-3 个最新目录,这对我来说效果很好。 ls | tail -2
【解决方案4】:

如果您的目录按照您的问题建议的那样命名为 YYYYMMDD,请利用字母顺序排列。

将所有目录放在一个数组中,然后选择第一个

dirs=(*/); first_dir="$dirs";

(这实际上是first_dir="${dirs[0]}";的快捷方式。)

同样,对于最后一个

dirs=(*/); last_dir="${dirs[$((${#dirs[@]} - 1))]}";

语法丑陋,但它被分解为:

# Create an array of all directories inside the working directory.
dirs=(*/);

# Get the number of entries in the array.
num_dirs=${#dirs[@]};

# Calculate the index of the last entry.
last_index=$(($num_dirs - 1));

# Get the value at the last index.
last_dir="${dirs[$last_index]}";

我知道这是一个已被接受的老问题,但我认为这种方法更可取,因为它可以在 Bash 中完成所有工作。没有理由产生额外的进程,更不用说parse the output of ls。 (诚​​然,在这种 YYYYMMDD 名称的特殊情况下应该没问题。)

【讨论】:

  • supertrue:不在 Bash 中,或者至少我不知道。您是否在普通的旧 Bourne shell sh 中尝试过它?
  • 不,我使用 Bash(Mac 终端),我只是想知道它是什么意思,因为 # 也用于 cmets。
  • 啊,我明白了。当它位于带有大括号的变量中时,它具有特殊含义。 ${#foo} 计算名为foo 的普通(字符串)变量中的字符数,${foo[@]} 计算名为foo 的数组中的元素数。见Bash parameter expansion
【解决方案5】:

基于 ls 的解决方案的问题在于它们不仅仅针对目录进行过滤。我认为:

cp `find . -mindepth 1 -maxdepth 1 -type d  -exec stat -c "%Y %n" {} \;  |sort -n -r |head -1 |awk '{print $2}'`/* /target-directory/.

可能会起作用,但请注意,这只会复制直接目录中的文件。如果您想要一个更通用的答案来将最新目录下的任何内容复制到新目录,我认为您最好使用 rsync,例如:

rsync -av `find . -mindepth 1 -maxdepth 1 -type d  -exec stat -c "%Y %n" {} \;  |sort -n -r |head -1 |awk '{print $2}'`/ /target-directory/ 

但这取决于您想要哪种行为。反引号里的东西的解释是:

  • . - 当前目录(你可以在这里指定一个绝对路径)
  • -mindepth/-maxdepth - 仅将 find 命令限制为当前目录的直接子目录
  • -type d - 仅目录
  • -exec stat .. - 从 find 中输出修改时间和目录名称
  • sort -n -r |head -1 | awk '{print $2}' - date 对目录进行排序并输出最近修改的名称

【讨论】:

    【解决方案6】:

    请尝试以下命令
    ls -1tr |尾 -1

    【讨论】:

      【解决方案7】:

      我编写了一个命令,可用于识别文件夹中创建的哪些文件夹或文件是最新的。这似乎很纯粹:)

      #/bin/sh
      path=/var/folder_name
      
      newest=`find $path -maxdepth 1 -exec stat -t {} \; |sed 1d |sort -r -k 14 | head -1 |awk {'print $1'} | sed 's/\.\///g'`
      
      find $path -maxdepth 1| sed 1d |grep -v $newest
      

      【讨论】:

        【解决方案8】:
        find ~ -type d | ls -ltra
        

        这是我最近学到的简单实用的。 此命令将按时间倒序显示结果。

        【讨论】:

        • ls 不使用管道
        猜你喜欢
        • 2019-11-11
        • 1970-01-01
        • 2015-05-21
        • 1970-01-01
        • 2011-05-21
        • 2013-10-12
        • 1970-01-01
        • 2012-11-02
        • 2011-12-16
        相关资源
        最近更新 更多