Mover arquivos da origem para o destino nas categorias [closed]

1

Atualmente estou aprendendo o script bash e tentando escrever um script que mova arquivos da origem para um diretório de destino e categorize os arquivos com base na primeira letra e crie um subdiretório baseado na primeira letra.

Categorias:

  • A-F
  • G-L
  • M-R
  • S-Z
  • #

Isso é o que escrevi até agora e não sei como continuar:

move.sh

echo "Enter the source"
read SOURCE

echo "Enter the destination"
read DESTINATION

for file in $SOURCE;do
    case ${file:0:1} in
      {a..f} ) echo "Belongs to A-F";
        if [ -d $DESTINATION/A-F ]
        then mv file $DESTINATION/A-F
        else mkdir $DESTINATION/A-F
      {g..l} ) echo "Belongs to G-L";
        if [ -d $DESTINATION/G-L ]
        then mv file $DESTINATION/G-L
        else mkdir $DESTINATION/G-L
      {m..r} ) echo "Belongs to M-R";
        if [ -d $DESTINATION/M-R ]
        then mv file $DESTINATION/M-R
        else mkdir $DESTINATION/M-R
      {s..z} ) echo "Belongs to S-Z";
        if [ -d $DESTINATION/S-Z ]
        then mv file $DESTINATION/S-Z
        else mkdir $DESTINATION/S-Z
        { } ) echo "Belongs to #";
        if [ -d $DESTINATION/# ]
        then mv file $DESTINATION/#
        else mkdir $DESTINATION/#
    esac
exit 0

Exemplo:

Eu fiz o download de arquivos no diretório Downloads

  

aa1.jpg, gg2.mp3, zo1.mkv, 01010.pdf

sh move.sh 


Enter the source
/Downloads

Enter the destination
/Documents

Depois de executar o script, devo receber:

/Documents/#/01010.pdf
/Documents/A-F/aa1.jpg
/Documents/G-L/gg2.mp3
/Documents/S-Z/zo1.mkv
    
por Jsdude 08.05.2017 / 17:43

2 respostas

1

Eu notei alguns erros no seu script:

Isso deve produzir o resultado que você está procurando:

#!/bin/bash

echo "Enter the source"
read SOURCE

echo "Enter the destination"
read DESTINATION

for file in $SOURCE/*; do
  base='basename "${file}"'
  letter=${base:0:1}

  case $letter in
    [a-f]) echo "A-F";
     if [ -d "$DESTINATION/A-F" ]; then
       echo "Moving file..."
       mv $file "$DESTINATION/A-F"
     else
      mkdir -p "$DESTINATION/A-F";
     fi
    ;;
    [g-l]) echo "G-L"
      if [ -d "$DESTINATION/G-L" ]; then
        echo "Moving file..."
        mv $file "$DESTINATION/G-L"
      else
        mkdir -p "$DESTINATION/G-L"
      fi
    ;;
    [m-r]) echo "M-R"
      if [ -d "$DESTINATION/M-R" ]; then
        echo "Moving file..."
        mv $file "$DESTINATION/M-R"
      else
        mkdir -p "$DESTINATION/M-R"
      fi
    ;;
    [s-z]) echo "S-Z";
      if [ -d "$DESTINATION/S-Z" ]; then
        echo "Moving file..."
        mv $file "$DESTINATION/S-Z"
      else
        mkdir -p "$DESTINATION/S-Z";
      fi
    ;;
    *) echo "-"
      if [ -d "$DESTINATION/-" ]; then
        echo "Moving file..."
        mv $file "$DESTINATION/-"
      else
        mkdir -p "$DESTINATION/-";
      fi
  esac
done
    
por Raghib Hasan 08.05.2017 / 19:22
1

Eu sugiro fazer os diretórios antes tentando mover os arquivos, não depois. Além disso, pule a verificação da existência do diretório, apenas use

mkdir -p

Também não acho que você precise de todas essas condicionais complexas, embora a simplicidade esteja na mente do observador, eu acho. Para mim, algo parecido com o seguinte parece mais simples.

#!/bin/bash

# repeats until you enter a valid directory
while [ ! -d "$DESTINATION_ANY_VALID_FORM" ]; do
      read -p "Enter destination directory:" DESTINATION_ANY_VALID_FORM
done

# canonicalizes directory name into a standard form
DESTINATION="$(readlink -f "$DESTINATION_ANY_VALID_FORM")"

# same deal for source
while [ ! -d "$SOURCE_ANY_VALID_FORM" ]; do
      read -p "Enter source directory:" SOURCE_ANY_VALID_FORM
done

SOURCE="$(readlink -f "$SOURCE_ANY_VALID_FORM")"

# makes the directories you want if they don't exist already - 
# conditionals aren't needed.
mkdir -p $DESTINATION/A-F
mkdir -p $DESTINATION/G-L
mkdir -p $DESTINATION/M-R
mkdir -p $DESTINATION/S-Z
mkdir -p $DESTINATION/#

# And then move the files any way you want. There must eleventy-twelve ways. 
# I was wrong thinking wildcards would be easy. 
# That is actually kind of hard. 
# The following is easy to write and understand, but there are more efficient ways.

ls -w1 "$SOURCE" | grep ^[a-f,A-F] | while read FILE ; do
       mv --verbose --backup --target-directory="$DESTINATION/A-F" "$SOURCE/$FILE"  
done

ls -w1 "$SOURCE" | grep ^[g-l,G-L] | while read FILE ; do
       mv --verbose --backup --target-directory="$DESTINATION/G-L" "$SOURCE/$FILE"  
done

ls -w1 "$SOURCE" | grep ^[m-r,M-R] | while read FILE ; do
       mv --verbose --backup --target-directory="$DESTINATION/M-R" "$SOURCE/$FILE"
done

ls -w1 "$SOURCE" | grep ^[s-z,S-Z] | while read FILE ; do
       mv --verbose --backup --target-directory="$DESTINATION/S-Z" "$SOURCE/$FILE"
done

ls -w1 "$SOURCE" | grep ^[0-9] | while read FILE ; do
       mv --verbose --backup --target-directory="$DESTINATION/#" "$SOURCE/$FILE"
done

versão paste-bin: link

    
por Lew Rockwell Fan 08.05.2017 / 18:06