script para agrupar diretórios de intervalos aleatórios em uma dada ordem usando o shell script

1

1) Eu tenho diretórios de 0 a 3120203 (diretórios de notas não estão em sequência, eles são aleatórios)

-bash-4.1$ ls
0        1261826  211205   2398339  267475   295482   339902  395546  457254  503959  538784  583032  643106  78093   906653
1000791  126359   211250   2398362  267592   295488   340070  39565   457378  504052  538846  583103  643168  78143   91594
1001022  126944   2114355  2398373  267667   29583    341088  395652  457471  504160  540470  583316  64447   781579  91777
1002557  127163   2129010  2398380  267771   2959608  341300  395786  457628  504219  540632  583875  645373  782220  921760
1004183  127316   2129165  2398388  268076   296331   341452  396207  457758  504278  541300  583998  645437  78227   924976
1004399  127416   2132965  2398396  2681923  296456   341512  39720   457820  504337  541754  584219  645816  782272  925382
1005369  130416   2137199  2398482  268333   2964801  341688  39779   457879  504404  541994  584278  645876  782704  928134

2) Eu quero classificar e agrupar todos os diretórios e movê-lo sob um intervalo específico de 50000.

por exemplo: diretórios de 0 a 50000 devem se mover abaixo de 50000, de 50001 a 100000 para menos de 100.000 e assim por diante. as iterações devem ser de 50000

Eu não sou especialista em scripts de shell:

aqui está o meu script de shell:

#!/bin/bash
#set -x
#Please pass document library path
SOURCE=/opt/dms/
DEST=/opt/nes_dms
cd $SOURCE
ls | sort -n >> /opt/ncm/list.txt
for dir in 'cat /opt/ncm/list.txt'
do
#echo $dir
if [ "$dir" -le "50000" ]
then
echo $dir is less then $i
mv $dir $DEST
fi
done

Eu preciso que o script seja incrementado automaticamente por 50000 + 50000 = 100000 e mova todos os diretórios entre 50001 a 100000 em 100000 dir até lermos todos os dir em um arquivo.

    
por Nitin Mestry 08.04.2018 / 19:14

3 respostas

1
#!/bin/bash
#set -x
#Please pass document library path
SOURCE='/crypto/home/hl/tmp/stackexchange/dir_groups/source'
DEST='/crypto/home/hl/tmp/stackexchange/dir_groups/target'
declare -a target_dir_indexes
cd "$SOURCE" || exit 1
for dir in *; do
    test "$DEBUG" = 'yes' && echo "$dir"
    test -d "$dir" && ! test -L "$dir" || continue
    if ! [[ "$dir" =~ ^(0|[1-9][0-9]*)$ ]]; then
        echo "error: dir name '${dir}'; skipping"
        continue
    fi
    target_index=$((dir/50000))
    if [ "$dir" -gt 0 ]; then
        if [ $((dir%50000)) -eq 0 ]; then
            ((target_index--))
        fi
    fi
    target_dir_name=$(((target_index+1)*50000))
    target_dir_path="${DEST}/${target_dir_name}"
    # avoid unneccessary calls to mkdir or the VFS
    if [ -z "${target_dir_indexes[target_index]}" ]; then
        mkdir -p "$target_dir_path"
        target_dir_indexes[target_index]=1
    fi
    echo "${dir} is moved to ${target_dir_name}"
    mv -i "$dir" "$target_dir_path"
done
    
por 08.04.2018 / 19:40
1

A matemática é um pouco complicada. Uma divisão inteira simples (file/50000+1)*50000 falhará. Se o número do arquivo for 50000, o resultado será 100000. Não é o que você deseja. Precisamos de uma mudança de origem:

$(( ((file-1)/50000+1)*50000 ))

Além disso, um esquema de código mais simples está ok:

#!/bin/bash
fsource=/opt/dms;    fdest=/opt/nes_dms;    istep=50000
cd "$fsource"
for f In *; do
    i=$(( 1+(f-1)/istep ))              # Which bucket?
    fd="$fdest/$(( istep*i ))"
    echo  \
    mv -t "$fd" "$f"
done

Adicionando algumas verificações [(é um diretório?) E (somente dígitos)]:

#!/bin/bash
fsource=/opt/dms/;     fdest=/opt/nes_dms;     istep=50000
for f in "$fsource"/*; do
    [[ -d $f ]] || continue           # Is a dir?
    i=${f##*/}                        # Remove path.                                                  
    [[ $i =~ ^[0-9]+$ ]] || continue  # Only digits?                                                  
    i=$((1+(i-1)/istep))              # Which bucket?
    fd="$fdest/$(( istep*i ))"
    echo  \
                       mv -t "$fd" "$f"
done

Comente o eco quando estiver satisfeito com os valores e quiser executar os movimentos.

    
por 08.04.2018 / 22:06
1

WARN: o script abaixo não manipula erros quando o diretório não é nomeado numérico.

Solução posible:

#!/bin/bash
#set -x

SOURCE=/opt/dms/
DEST=/opt/nes_dms

for dir in 'ls $SOURCE | sort -n'
do

  # define destination subdir
  dst_dir=$(( (($dir/50000) + 1) * 50000 ))

  # check if destination subdir exists
  if [ ! -d $DEST/$dst_dir ]
  then
    mkdir $DEST/$dst_dir
  fi 

  mv $SOURCE/$dir $DEST/$dst_dir

done
    
por 08.04.2018 / 19:38