thi*_*oso 3 shell scripting bash shell-script
我正在处理数千个文件,其名称包含从 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
Run Code Online (Sandbox Code Playgroud)
依此类推,直到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
Run Code Online (Sandbox Code Playgroud)
等等。并且应该根据文件名中的等效日期将文件移动到这些目录。例如:200101xx
名称中包含的所有文件都应移动到该2001/01
文件夹中。
使用 bash 实现这一目标的最直接方法是什么?
如果我理解正确,这是我的建议:
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
Run Code Online (Sandbox Code Playgroud)
循环几年和几个月:
#!/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
Run Code Online (Sandbox Code Playgroud)
如果您每年和每月有太多长名称的文件(您声称为“数千”),则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
Run Code Online (Sandbox Code Playgroud)