我有一个目录,其中包含从 img001.jpg 到 img101693.jpg 的 101695 个文件,我想将每 100 个图像移动到另一个目录。我发现了一些类似的帖子,例如如何复制文件夹中的每 4 个文件但这些假定所有文件中序列号的位数相同,因此我的范围需要以 img000001.jpg 开头 有没有办法做到这一点,或者我是否需要修改我的文件名,以便它们都具有连续剧中的字符数相同吗?
答案1
假设您最终希望将这些文件以 100 个为一组分散到多个dir0000
...dir1016
目录中,位于zsh
:
files=( img*.jpg(N.n) )
typeset -Z4 n=0
while (( $#files )); do
mkdir -p dir$n && cp -- $files[1,100] dir$n/
(( n++ ))
files[1,100]=()
done
globn
限定符按数字对文件进行排序。typeset -Z4
零填充$n
扩展至长度 4。
使用zsh
s zmv
,您还可以同时复制file<n>.jpg
并dir<n/100>
修复位数:
zmodload zsh/files
mkcp() { mkdir -p -- $2:h && cp -- "$@"; }
autoload -Uz zmv
zmv -Pmkcp -n 'img(<->).jpg' \
'dir${(l[4][0])$(( $1 / 100 ))}/img${(l[6][0])1}.jpg'
(-n
如果满意,请删除(试运行))。
答案2
我有一个包含这些虚拟文件的测试目录:
$ ls img*
img0003.jpg img001.jpg img013.jpg img02.jpg img10.jpg img12.jpg
让我们使用TXR 口齿不清将它们以 2 组为一组移动,或者至少模拟移动它们到一系列目录:dir001
, dir002
, ...:
$ txr move.tl
move img001.jpg -> dir001
move img02.jpg -> dir001
move img0003.jpg -> dir002
move img10.jpg -> dir002
move img12.jpg -> dir003
move img013.jpg -> dir003
代码在move.tl
:
(defun normalize (path)
(collect-each ((tok (tok-str path #/\d+/ t))
(i 0))
(if (oddp i) (toint tok) tok)))
(flow
(glob "img*.jpg")
(sort @1 : normalize)
(tuples 2)
(do each ((tuple @1)
(dirnum 1))
(each ((file tuple))
(put-line `move @file -> dir@(pic "0##" dirnum)`))))
该normalize
函数将字符串转换img001.jpg
为交替标记:不包含数字的标记和包含数字的标记。数字标记被转换为整数类型。来自 REPL 的示例:
1> (normalize "img001.jpg")
("img" 1 ".jpg")
2> (normalize "123img001.jpg")
("" 123 "img" 1 ".jpg")
3> (normalize "123img001.jpg42")
("" 123 "img" 1 ".jpg" 42 "")
我们使用这个normalize
函数作为对名称进行排序的基础:
4> (glob "img*.jpg")
("img0003.jpg" "img001.jpg" "img013.jpg" "img02.jpg" "img10.jpg"
"img12.jpg")
5> (sort *4)
("img0003.jpg" "img001.jpg" "img013.jpg" "img02.jpg" "img10.jpg"
"img12.jpg")
没用的命令!让我们引入normalize
:
6> [sort *4 : normalize]
("img001.jpg" "img02.jpg" "img0003.jpg" "img10.jpg" "img12.jpg"
"img013.jpg")
从那里开始,只需分组为我们想要的组大小并移动到目录即可。在上面的程序中,这只是用 print 语句模拟的。在以下修改后的程序中,实际创建了目录并移动了文件:
(defun normalize (path)
(collect-each ((tok (tok-str path #/\d+/ t))
(i 0))
(if (oddp i) (toint tok) tok)))
(flow
(glob "img*.jpg")
(sort @1 : normalize)
(tuples 2)
(do each ((tuple @1)
(dirnum 1))
(each ((file tuple))
(let ((dirname (pic "dir0##" dirnum)))
(put-line `move @file -> @dirname`)
(ensure-dir dirname)
(rename-path file (path-cat dirname file))))))
跑步:
$ txr move.tl
move img001.jpg -> dir001
move img02.jpg -> dir001
move img0003.jpg -> dir002
move img10.jpg -> dir002
move img12.jpg -> dir003
move img013.jpg -> dir003
$ ls *.jpg
ls: cannot access '*.jpg': No such file or directory
$ ls dir*
dir001:
img001.jpg img02.jpg
dir002:
img0003.jpg img10.jpg
dir003:
img013.jpg img12.jpg