![使用 find 移动和组织文件](https://linux22.com/image/230774/%E4%BD%BF%E7%94%A8%20find%20%E7%A7%BB%E5%8A%A8%E5%92%8C%E7%BB%84%E7%BB%87%E6%96%87%E4%BB%B6.png)
我在 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
_
-
20240301
date
20240301
然后通过 perl 替换进行传递,在前 4 个字符之后插入一个空格,在接下来的两个字符之后插入一个空格,在接下来的两个字符之后再插入一个空格。所以20240301
就变成了2024 03 01
,这read
将被保存2024
为$year
,03
as$month
和01
as $day
(我在这里假设标准日期,如果您使用美式风格,请更改这些变量名称的顺序)。
然后,我们创建一个$target
变量来保存我们要创建的目录的名称,使用outDir
我们在开始时定义的父目录 udner,其他目录将被创建,在最后一步中,假设成功mkdir -p
(它将是,即使目录已经存在,但如果无法访问目标则不会),我们将文件复制过来。