如何根据文件大小将多个文件分离到子目录中?

SID*_*RTH 5 command-line bash files

我有一堆视频文件,我想根据我决定的文件大小将它们分开。

例子:

文件夹BB有 15 个不同文件大小的文件。

我将子文件夹设置为:

  1. less than 100 MB -- folder A
  2. 100 MB to 500 MB -- folder B
  3. more than 500 MB -- folder C

因此,它可以通过 Bash 或脚本来完成,而不是手动完成。

我有一个大致的想法,find命令和适当的 if else 会起作用,但不知道如何编写脚本。

无论如何,一个通用的编程框架是:

float _size=[file_size]; // Reads the file size

if(_size<100)    // File size is less than 100 MB
  {  exec mv [file] /A/* ; // Move to folder A }
else if(_size>500) // File size is greater than 500 MB
  {  exec mv [file] /C/* ; // Move to folder C }
else if((_size<=500)||(_size>=100)) //file size is between 100 to 500
  {  exec mv [file] /B/* ; // Move to folder C}
else
  {print("file error");}
Run Code Online (Sandbox Code Playgroud)

所以我希望这很容易做到。以上只是我会做的一般想法。

des*_*ert 7

我建议使用此for循环遍历当前目录中的所有文件:

for i in *; do
  size=$(stat --printf="%s" "$i")
  if [ $size -lt 100000000 ]; then
      mv "$i" A/
  elif [ $size -lt 500000000 ]; then
      mv "$i" B/
  else
      mv "$i" C/
  fi
done
Run Code Online (Sandbox Code Playgroud)

您请求Megabyte,如果您确实想要 100/500 Mebibyte使用104857600524288000相应地。

如果目录包含其他文件并且您只想处理例如.avi文件,请使用:

for i in *.avi; do …
Run Code Online (Sandbox Code Playgroud)

说明

  • for i in *; do … ; done – 遍历当前目录中的所有文件
  • size=$(stat --printf="%s" "$i")– 使用以字节为单位获取文件大小stat并将其保存为变量size
  • if A; then B; elif C; then D; else E; fi – 如果 A 是真的做 B,否则如果 C 是真的做 D,否则做 E
  • [ $size -lt X ]– 测试是否sizeless than X
  • mv "$i" Y/ – 将当前处理的文件移动到文件夹 Y 中


ste*_*ver 7

你可以用 GNU 做这种事情,find例如

find BB/ -type f \( -size -100M -exec mv -t A/ {} + \
  -o -size +500M -exec mv -t C/ {} + -o -exec mv -t B/ {} + \)
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 如果要移动的文件在同一树内(例如A/B/C/是子目录BB),那么你就需要防止find递归到这些,使用-maxdepth-prune例如。

  • 由于 的舍入行为,需要小心-size。在这种情况下这不是问题,但例如-size -1M会将所有小于 1024kB 的文件舍入到 1M,以便只有空文件匹配。

为方便起见,使用千字节大小的文件进行测试:

$ tree -h somepath/
somepath/
??? [   0]  file0
??? [100K]  file100
??? [150K]  file150
??? [200K]  file200
??? [250K]  file250
??? [300K]  file300
??? [350K]  file350
??? [400K]  file400
??? [450K]  file450
??? [ 50K]  file50
??? [500K]  file500
??? [550K]  file550
??? [600K]  file600

0 directories, 13 files
Run Code Online (Sandbox Code Playgroud)

然后

$ find somepath/ -type f \( -size -100k -exec mv -vt A/ {} + \
>   -o -size +500k -exec mv -vt C/ {} + -o -exec mv -vt B/ {} + \)
'somepath/file50' -> 'A/file50'
'somepath/file0' -> 'A/file0'
'somepath/file550' -> 'C/file550'
'somepath/file600' -> 'C/file600'
'somepath/file250' -> 'B/file250'
'somepath/file200' -> 'B/file200'
'somepath/file100' -> 'B/file100'
'somepath/file300' -> 'B/file300'
'somepath/file500' -> 'B/file500'
'somepath/file350' -> 'B/file350'
'somepath/file450' -> 'B/file450'
'somepath/file400' -> 'B/file400'
'somepath/file150' -> 'B/file150'
Run Code Online (Sandbox Code Playgroud)

给予

$ tree -h A B C
A
??? [   0]  file0
??? [ 50K]  file50
B
??? [100K]  file100
??? [150K]  file150
??? [200K]  file200
??? [250K]  file250
??? [300K]  file300
??? [350K]  file350
??? [400K]  file400
??? [450K]  file450
??? [500K]  file500
C
??? [550K]  file550
??? [600K]  file600

0 directories, 13 files
Run Code Online (Sandbox Code Playgroud)