Как отделить несколько файлов на основе размера файла в подкаталог?

У меня есть куча видеофайлов, которые я бы хотел разделить на основе размера файла, который я решил.

Пример:

Папка BB имеет 15 файлов различного размера файла.

У меня есть подпапка, установленная как:

less than 100 MB -- folder A 100 MB to 500 MB -- folder B 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");}

Так что я надеюсь, что это легко сделать. Выше была только общая идея, которую я бы сделал.

5
задан 8 October 2017 в 00:20

6 ответов

Я предлагаю перебрать все файлы в текущем каталоге с помощью этого цикла 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

Вы запросили мегабайт, если вы действительно хотели использовать 100/500 Mebibyte 104857600 и 524288000 соответственно.

Если каталог содержит другие файлы, и вы просто хотите обработать, например .avi, используйте:

for i in *.avi; do …

Пояснения

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 ] - проверьте, size l ess t han X mv "$i" Y/ - переместить текущий обработанный файл внутри папки Y
7
ответ дан 22 May 2018 в 17:46
  • 1
    можете ли вы упомянуть №1. какой синтаксис используется для чтения размера файла? , # 2. Linux будет показывать размер файла в битах или байтах? – SIDDHARTH 7 October 2017 в 18:52
  • 2
    @SIDDHARTH Я добавлю подробные объяснения позже, но пока: вывод stat --printf="%s" "$i" (где переменная i содержит обработанное имя файла) сохраняется как переменная size, stat печатает много информации о файле и выводит можно управлять с помощью опции --printf, %s означает «общий размер, в байтах» здесь. См. man stat . – dessert 7 October 2017 в 19:00

Я предлагаю перебрать все файлы в текущем каталоге с помощью этого цикла 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

Вы запросили мегабайт, если вы действительно хотели использовать 100/500 Mebibyte 104857600 и 524288000 соответственно.

Если каталог содержит другие файлы, и вы просто хотите обработать, например .avi, используйте:

for i in *.avi; do …

Пояснения

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 ] - проверьте, size l ess t han X mv "$i" Y/ - переместить текущий обработанный файл внутри папки Y
7
ответ дан 18 July 2018 в 05:38

Я предлагаю перебрать все файлы в текущем каталоге с помощью этого цикла 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

Вы запросили мегабайт, если вы действительно хотели использовать 100/500 Mebibyte 104857600 и 524288000 соответственно.

Если каталог содержит другие файлы, и вы просто хотите обработать, например .avi, используйте:

for i in *.avi; do …

Пояснения

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 ] - проверьте, size l ess t han X mv "$i" Y/ - переместить текущий обработанный файл внутри папки Y
7
ответ дан 24 July 2018 в 18:23

Вы можете делать такие вещи с помощью GNU find, например

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

ПРИМЕЧАНИЯ:

Если вы хотите перемещать файлы в одном и том же дереве (например, A/ , B/, C/ являются подкаталогами BB), тогда вам нужно будет предотвратить find от повторения в них, например, с помощью -maxdepth или -prune. Забота необходима из-за поведения округления -size. Это не проблема с этим случаем, но, например, -size -1M будет охватывать все файлы размером менее 1024 КБ до 1 М, что соответствует только пустым файлам.

Тестирование с помощью файлов размером в килобайт для удобства:

$ 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

, затем

$ 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'

с

$ 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
6
ответ дан 22 May 2018 в 17:46
  • 1
    Просто потрясающе, спасибо за обмен! Однако, поскольку запросы OP MB и (я полагаю) имеет в виду 1000 значений, правильно ли использовать -size -100000000c (это 100 000 000) для этого? Btw tree имеет опцию --sort=size. – dessert 7 October 2017 в 21:57
  • 2
    @dessert да, они могут использовать любой из суффиксов, перечисленных в man find, чтобы получить требуемые точные размеры – steeldriver 8 October 2017 в 02:20
  • 3
    Это еще один способ сделать это. Это доказывает, что существует многообразный подход и способы сделать то же самое. Как я уже упоминал ранее, у меня возникла идея, что правильный сценарий с командой find и if-else будет работать с моей точки зрения. Спасибо и steeldriver, и @dessert, чтобы помочь мне закодировать сценарий. – SIDDHARTH 8 October 2017 в 11:39

Вы можете делать такие вещи с помощью GNU find, например

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

ПРИМЕЧАНИЯ:

Если вы хотите перемещать файлы в одном и том же дереве (например, A/ , B/, C/ являются подкаталогами BB), тогда вам нужно будет предотвратить find от повторения в них, например, с помощью -maxdepth или -prune. Забота необходима из-за поведения округления -size. Это не проблема с этим случаем, но, например, -size -1M будет охватывать все файлы размером менее 1024 КБ до 1 М, что соответствует только пустым файлам.

Тестирование с помощью файлов размером в килобайт для удобства:

$ 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

, затем

$ 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'

с

$ 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
6
ответ дан 18 July 2018 в 05:38

Вы можете делать такие вещи с помощью GNU find, например

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

ПРИМЕЧАНИЯ:

Если вы хотите перемещать файлы в одном и том же дереве (например, A/ , B/, C/ являются подкаталогами BB), тогда вам нужно будет предотвратить find от повторения в них, например, с помощью -maxdepth или -prune. Забота необходима из-за поведения округления -size. Это не проблема с этим случаем, но, например, -size -1M будет охватывать все файлы размером менее 1024 КБ до 1 М, что соответствует только пустым файлам.

Тестирование с помощью файлов размером в килобайт для удобства:

$ 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

, затем

$ 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'

с

$ 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
6
ответ дан 24 July 2018 в 18:23
  • 1
    Просто потрясающе, спасибо за обмен! Однако, поскольку запросы OP MB и (я полагаю) имеет в виду 1000 значений, правильно ли использовать -size -100000000c (это 100 000 000) для этого? Btw tree имеет опцию --sort=size. – dessert 7 October 2017 в 21:57
  • 2
    @dessert да, они могут использовать любой из суффиксов, перечисленных в man find, чтобы получить требуемые точные размеры – steeldriver 8 October 2017 в 02:20
  • 3
    Это еще один способ сделать это. Это доказывает, что существует многообразный подход и способы сделать то же самое. Как я уже упоминал ранее, у меня возникла идея, что правильный сценарий с командой find и if-else будет работать с моей точки зрения. Спасибо и steeldriver, и @dessert, чтобы помочь мне закодировать сценарий. – SIDDHARTH 8 October 2017 в 11:39

Другие вопросы по тегам:

Похожие вопросы: