Cómo mover todos los archivos de varios directorios a sus directorios principales usando bash

Cómo mover todos los archivos de varios directorios a sus directorios principales usando bash

Tengo la siguiente estructura de archivos:

  • /inicio/datos/C01/dir_wwe_346/archivo1.txt pic.jpg aleatorio.sh
  • /inicio/datos/C02/dir_wwe_644/archivo1.txt pic.jpg aleatorio.sh
  • /inicio/datos/C03/dir_wwe_324/archivo1.txt pic.jpg aleatorio.sh

Quiero que sean así:

  • inicio/datos/C01/archivo1.txt pic.jpg aleatorio.sh
  • inicio/datos/C02/archivo1.txt pic.jpg aleatorio.sh
  • inicio/datos/C03/archivo1.txt pic.jpg aleatorio.sh

Básicamente se trata de mover varios archivos un directorio hacia arriba. Probé este script sin éxito:

#!/bin/bash for i in */ do cd i/*/ mv * ../ done


Después de publicar esto (pero antes de leer la respuesta de Grawity a continuación), me di cuenta de que no usé la expansión de variables adecuada y ejecuté esto:

#!/bin/bash for i in */ do cd ${i}*wwe* mv * ../ done

El script mueve todos los subdirectorios a la carpeta de datos, por lo que termino con esto:

  • /hogar/C01/dir_wwe_346/archivo1.txt pic.jpg aleatorio.sh
  • /hogar/C02/dir_wwe_644/archivo1.txt pic.jpg aleatorio.sh
  • /hogar/C03/dir_wwe_324/archivo1.txt pic.jpg aleatorio.sh

    ¿Qué estoy haciendo mal?


PD. Edité la publicación para que revele el proceso por el que pasé y para que las respuestas tengan más sentido para los recién llegados que podrían beneficiarse de ellas. Gracias gracity, aprendí algo nuevo. Acabo de empezar a aprender bash hace una semana y siento que estoy progresando.

Respuesta1

  1. Las variables sólo se reconocen y amplían con el $prefijo. Si el bucle define una variable 'i', debes usar$icuando quieras su valor:

    for i in */; do
        cd $i/*/
    
  2. El "directorio actual" abarca todo el proceso y no restablece automáticamente cada iteración del bucle. Luego deberá regresar manualmente al directorio principal:

    cd $i/*/; mv * ../; cd ../../
    

    o utilice una "subshell" para determinar el alcance del cambio de directorio:

    (cd $i/*/; mv * ../)
    
  3. No estás haciendo ninguna comprobación de errores. Si cdalguna vez falla, lo siguiente mvpuede causar cosas desagradables. Combine comandos usando &&o haga lo contrario, verifique y use || exit(o || break), lo que se vea mejor:

    for i in */; do
        cd $i/*/ && {
            mv * ../;
            cd ../../
        }
    done
    
    for i in */; do
        cd $i/*/ || exit
        mv * ../
        cd ../../
    done
    
    for i in */; do
        (cd $i/*/ && mv * ../)
    done
    
  4. Mejora: puede mover el comodín del subdirectorio a mv, lo que le permitirá funcionar incluso en caso de que haya varios subdirectorios:

    cd $i/ || exit
    mv */* .
    cd ../
    
  5. Mejora: podrías hacer esto sin necesidad cdde:

    mv $i/*/* $i/
    

información relacionada