序列化不一致时如何复制每N个文件

序列化不一致时如何复制每N个文件

我有一个目录,其中包含从 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。

使用zshs zmv,您还可以同时复制file<n>.jpgdir<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

相关内容