Bash - 如何根据名称中的日期重新组织文件?

Bash - 如何根据名称中的日期重新组织文件?

我正在处理数千个文件,其名称包含从 2001-01-01 到 2020-12-31 的连续日期。

此类文件的示例如下:

gpm_original_20010101.nc
gpm_cressman_20010101_cor_method-add_fac-0.5_pass-1_radius-500km.nc
gpm_cressman_20010101_cor_method-add_fac-0.5_pass-2_radius-250km.nc
gpm_cressman_20010101_cor_method-add_fac-0.5_pass-3_radius-150km.nc
gpm_cressman_20010101_cor_method-add_fac-0.5_pass-4_radius-75km.nc
gpm_cressman_20010101_cor_method-add_fac-0.5_pass-5_radius-30km.nc
.
.
.
gpm_original_20010131.nc
gpm_cressman_20010131_cor_method-add_fac-0.5_pass-1_radius-500km.nc
gpm_cressman_20010131_cor_method-add_fac-0.5_pass-2_radius-250km.nc
gpm_cressman_20010131_cor_method-add_fac-0.5_pass-3_radius-150km.nc
gpm_cressman_20010131_cor_method-add_fac-0.5_pass-4_radius-75km.nc
gpm_cressman_20010131_cor_method-add_fac-0.5_pass-5_radius-30km.nc

依此类推,直到2020-12-31。我需要做的就是根据年份和月份将这些文件重新组织到新的文件夹中。

目录树需要遵循year子目录的逻辑months,如下所示:

2001
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12

2002
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12

等等。并且应根据文件名中的等效日期将文件移动到这些目录。例如:200101xx名称中包含的所有文件都应移动到该2001/01文件夹​​中。

使用 bash 实现此目的最直接的方法是什么?

答案1

如果我理解正确的话,这是我的建议:

for i in *.nc; do 
  [[ "$i" =~ _([0-9]{8})[_.] ]] && d="${BASH_REMATCH[1]}"
  mkdir -p "${d:0:4}/${d:4:2}"
  mv "$i" "${d:0:4}/${d:4:2}"
done

答案2

循环年份和月份:

#!/bin/bash

for year in {2001..2020} ; do
  mkdir $year
  for month in {01..12} ; do
    mkdir $year/$month
    mv gpm_cressman_${year}${month}* $year/$month
  done
done

如果您每年和每月有太多长名称的文件(您声称“数千”),bash可能会达到其限制(“参数列表太长”)。任何一个暂时增加 ulimit或使用xargs

#!/bin/bash

for year in {2001..2020} ; do
  mkdir $year
  for month in {01..12} ; do
    mkdir $year/$month
    find -maxdepth 1 -type f -name "gpm_cressman_${year}${month}*" |
      xargs -I '{}' mv '{}' $year/$month
  done
done

答案3

假设日期始终位于文件名中的相同位置,请将其放入脚本中:

#!/bin/bash
#
while $# -gt 0 ; do
    file="$1"
    shift
    year="$( echo "$file" | cut -c 14-17)"
    mnth="$( echo "$file" | cut -c 18-19)"
    [[ -d $year/$mnth ]] || mkdir -p $year/$mnth
    echo mv "$file" $year/$mnth
done

并使用以下命令调用脚本:

find . -maxdepth 1 -type f -name '*201*' -printf | \
    xargs -r the_script

man bash find xargs mkdir mv

echo当您真正想要这样做时,请删除。

相关内容