需要帮助创建子目录来存储其中包含日期的文件

需要帮助创建子目录来存储其中包含日期的文件

这是这个论坛的新手,但对于 RHEL 或脚本来说并不陌生。然而,这个有点让我烦恼。我有以下文件:

2019-05-01-00.34.00.msg 
2019-05-02-00.36.00.msg
2019-06-14-01.38.00.msg

我想将它们存储在这样的目录中:

/2019/05/01/<Filename>
/2019/05/02/<Filename>
/2019/06/14/<Filename>

我想在将它们放入目录时也保留当前文件名。另外,我想用 bash 来做到这一点。

有什么想法吗?

答案1

您可以循环遍历名称,拆分名称-,然后mkdir -p创建目录(如果不存在),最后移动。像这样的东西:

for file in *msg; do 
    IFS="-" read -r year month day rest  <<< "$file"
    dir="$year/$month/$day/" 
    mkdir -p -- "$dir"
    mv -- "$file" "$dir"
done

答案2

使用 perl 重命名工具这相当容易(不是util-linux 包中的重命名工具)。例如

设置:

$ touch 2019-05-01-00.34.00.msg 2019-05-02-00.36.00.msg 2019-06-14-01.38.00.msg
$ ls -l
total 2
-rw-r--r-- 1 cas cas 0 Oct 16 20:56 2019-05-01-00.34.00.msg
-rw-r--r-- 1 cas cas 0 Oct 16 20:56 2019-05-02-00.36.00.msg
-rw-r--r-- 1 cas cas 0 Oct 16 20:56 2019-06-14-01.38.00.msg

改名:

rename  -n '
  use File::Path qw(make_path);

  if (-f $_ && m/^\d{4}-\d{2}-\d{2}-/) {
    my ($y,$m,$d,$f) = split /-/,$_,4;
    make_path("$y/$m/$d");
    $_ = "$y/$m/$d/$f";
  }' *.msg

该脚本首先忽略非常规文件 ( -f) 或与模式不匹配的文件名^YYYY-MM-DD-。如果给出垃圾输入,这可以防止它创建不需要的目录。

它将文件名分成四个元素。前 3 个是嵌入在文件名中的年、月和日($y$m$d),第四个是文件名的其余部分($f)。

它使用make_path()来自的函数文件路径YYYY/标准模块,用于递归地创建,YYYY/MM/和的目录YYYY/MM/DD/(类似于命令-p的选项mkdir)。我本来可以运行 perlmkdir()函数三次,但我更喜欢使用File::Path.

$_然后它通过设置等于将文件重命名(即移动)到正确的目录中"$y/$m/$d/$f"

这是 perl 工作原理的关键rename。您可以使用任何perl 代码,从简单的s/foo/bar/搜索和替换样式到比这个答案中的脚本复杂得多的脚本。如果代码发生变化$_,那么文件就会被重命名。如果$_未更改,则不会重命名。

注意:这一行使用rename's-n选项,所以 a试运行仅有的。要使其真正重命名文件,请删除-n或将其更改-v为详细输出,如下所示:

2019-05-01-00.34.00.msg renamed as 2019/05/01/00.34.00.msg
2019-05-02-00.36.00.msg renamed as 2019/05/02/00.36.00.msg
2019-06-14-01.38.00.msg renamed as 2019/06/14/01.38.00.msg

顺便说一句,文件名可以提供给命令行(如上所示)或通过管道输入到脚本(rename有一个-0选项,因此它可以接受来自例如find ... -print0或任何其他可以输出 NUL 分隔列表的输入文件名)。

最后,rename不是-f覆盖现有文件,除非您使用aka选项告诉它--force

相关内容