使用 find 移动和组织文件

使用 find 移动和组织文件

我在 Debian GNU/Linux 12 (bookworm) x86_64 服务器上有一个文件夹,用作 NAS/Homelab 服务器,其中包含来自监控摄像头的大量文件。

MDAlarm_20240301-091804.jpg
...
MDAlarm_20240316-153813.jpg
MDAlarm_20240327-183713.jpg

如果我尝试使用(例如)移动文件,mv snap/*.jpg /path/to/dest/2024/03我会得到

-bash: /usr/bin/mv: Argument list too long

我在想类似的事情这个答案 find snap -name '*202403??-??????.jpg' -exec mv -t /path/to/dest/2024/03 {} +可以,但是是否有“一行”来为年份和月份创建适当的文件夹?

我正在将它们移至 samba 共享以查看和排序图片

答案1

首先,您并不严格需要拥有年份和月份文件夹。您可以使用以下命令移动它们find

find snap -name '*202403??-??????.jpg' -exec mv -t /path/to/dest {} +

现在,如果您需要按日期排列它们,并且如果我们可以假设您的所有文件都如您所示,MDAlarm_然后是日期,然后是 a,-时间后面是.jpg,没有空格或其他奇怪的字符,您可以做一些事情像这样:

outDir=/some/existing/directory
find snap -type f -name '*202403??-??????.jpg' | 
while read filename; do
  date=$(awk -F'[-_]' '{print $2}' <<<"$filename")
  read year month day < <(perl -pe 's/(....)(..)(..)/$1 $2 $3/' <<<"$date") 
  target="$outDir/$year/$month/$day"
  mkdir -p -- "$target" &&
     mv -- "$filename" "$target"
done

请注意,这还假设路径中文件名前的任何地方都没有-_字符。因此,如果您尝试这样做并且出现类似 的内容snap/some-dir/MDAlarm_20240301-091804.jpg,则它将失败。

该方法相对简单:我们运行find命令,然后解析输出。首先,我们使用文件名上的或awk字段分隔符来获取日期。如果您的文件始终类似于,那么由和定义的第二个字段将是日期。所以得到的值。-_MDAlarm_20240301-whatever_-20240301date20240301

然后通过 perl 替换进行传递,在前 4 个字符之后插入一个空格,在接下来的两个字符之后插入一个空格,在接下来的两个字符之后再插入一个空格。所以20240301就变成了2024 03 01,这read将被保存2024$year03as$month01as $day(我在这里假设标准日期,如果您使用美式风格,请更改这些变量名称的顺序)。

然后,我们创建一个$target变量来保存我们要创建的目录的名称,使用outDir我们在开始时定义的父目录 udner,其他目录将被创建,在最后一步中,假设成功mkdir -p(它将是,即使目录已经存在,但如果无法访问目标则不会),我们将文件复制过来。

相关内容