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

У меня есть 5000 файлов и 50 подкаталогов в одном каталоге. Я хочу переместить 100 файлов в каждый каталог. Может ли кто-нибудь подсказать, как это сделать? Заранее спасибо.

file_count=$(ls ABC* | wc -l)    
echo $file_count    
i=1    
dir_count=$(( file_count / 100))    
echo $dir_count    
dir_count1=`expr $dir_count + 1 `    
while [ $i -lt $dir_count1 ]    
do    
  mkdir $i
  i=`expr $i + 1`    
done    
    

Вот как я создал каталоги во время выполнения и хочу скопировать файлы, возвращаемые из первой строки скрипта, в каждый каталог. В каждой директории должно быть 100 файлов.

2
задан 23 May 2021 в 13:17

2 ответа

Вероятно, есть более элегантные способы сделать это. Но это работает

files_per_dir=100
file_count=$(ls -1 ABC* | wc -l)
dir_count=$((file_count / files_per_dir))
echo $dir_count
dir_count1=$(expr $dir_count + 1)
echo $dir_count1

for idir in $(seq 1 ${dir_count1}) ; do
  file_list=$(find . -maxdepth 1 -type f | grep -v au_ | head -${files_per_dir} | tr '\r\n' ' ')
  echo $file_list
  mkdir $idir
  mv $file_list $idir
done

Примечания:

  1. Я использовал grep -v au_ в трубе, чтобы избежать перемещения моего bash-скрипта (с именем au_...). Вам может понадобиться другая строка, или она вообще не нужна.
  2. Цикл seq заменяет ваш цикл while.
  3. ls -1 ABC* | wc -l можно заменить на ls ABC* | wc -w.
0
ответ дан 28 July 2021 в 11:36

Если вам не нужно какое-то "круговое" распределение файлов по различным новым каталогам, я бы предложил создавать целевые каталоги по мере необходимости, примерно так:

#!/bin/bash

shopt -s nullglob

nPer=100

files=( ABC* )

i=0; 
while (( i < ${#files[@]} )); do 
  if ! (( i % nPer )); then 
    newDir=dir$(( 1 + i/nPer ))
    echo mkdir -p "$newDir" || break
  fi
  echo mv -nt "$newDir" -- "${files[i]}"
  ((++i))
done

или POSIXly

#!/bin/sh

nPer=100

set -- ABC*

i=0;
while [ $# -gt 0 ] && [ -e "$1" ]; do
  if [ $((i % nPer)) -eq 0 ]; then
    newDir=dir$((1 + i/nPer))
    echo mkdir -p "$newDir" || break
  fi
  echo mv -nt "$newDir" -- "$1"
  shift
  i=$((i + 1))
done

Удалите echos, как только вы убедитесь, что все идет правильно.


Тестирование с nPer=10 и каталогом из 42 файлов ABC* (не кратным nPer, чтобы мы могли видеть, что происходит на краю):

$ ls ABC*
ABC01  ABC04  ABC07  ABC10  ABC13  ABC16  ABC19  ABC22  ABC25  ABC28  ABC31  ABC34  ABC37  ABC40
ABC02  ABC05  ABC08  ABC11  ABC14  ABC17  ABC20  ABC23  ABC26  ABC29  ABC32  ABC35  ABC38  ABC41
ABC03  ABC06  ABC09  ABC12  ABC15  ABC18  ABC21  ABC24  ABC27  ABC30  ABC33  ABC36  ABC39  ABC42

$ ./myscript
$ ls
dir1  dir2  dir3  dir4  dir5  myscript
$
$ ls dir?
dir1:
ABC01  ABC02  ABC03  ABC04  ABC05  ABC06  ABC07  ABC08  ABC09  ABC10

dir2:
ABC11  ABC12  ABC13  ABC14  ABC15  ABC16  ABC17  ABC18  ABC19  ABC20

dir3:
ABC21  ABC22  ABC23  ABC24  ABC25  ABC26  ABC27  ABC28  ABC29  ABC30

dir4:
ABC31  ABC32  ABC33  ABC34  ABC35  ABC36  ABC37  ABC38  ABC39  ABC40

dir5:
ABC41  ABC42
    
0
ответ дан 28 July 2021 в 11:36

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

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