Saltar al contenido

Bash Script para ordenar archivos en carpetas alfabéticas en ReadyNAS Duo v1

Solución:

Aquí hay un poco de un delineador que hará lo que quieras:

$ mkdir -p output/{A..Z}; for i in tstdir/*; do export FILE=$(basename "$i");  LTR=$(echo" ${FILE:0:1}" | tr [a-z] [A-Z]); mv "$i" "output/$LTR/$FILE" ; done

Aquí está el mismo comando en forma expandida para que pueda ver lo que está sucediendo:

$ mkdir -p output/{A..Z}
$ for i in tstdir/*; do 
    FILE=$(basename "$i")  
    LTR=$(echo "${FILE:0:1}" | tr [a-z] [A-Z])
    mv "$i" "output/$LTR/$FILE"
  done

Detalles

Lo anterior primero asume que el directorio de salida de solo las letras no existe y, por lo tanto, lo creará,

$ mkdir -p output/{A..Z}

los for El bucle funciona de la siguiente manera, recorriendo todos los archivos en tstdir/*. Luego determina el basename de esta ruta y la almacena en la variable, $FILE. Cada iteración a través del bucle se almacena en la variable $i.

FILE=$(basename "$i")

Luego usamos la capacidad de Bashes para devolver el primer carácter de la variable nombrada, $FILE, y luego usa tr para convertir cualquier carácter en minúsculas en mayúsculas.

LTR=$(echo "${FILE:0:1}" | tr [a-z] [A-Z])

Desglosando esto un poco más:

$ echo "${FILE:0:1}"
s
$ echo "${FILE:0:1}"
T

Con el tr código ahora puede ver lo que está pasando:

$ echo "${FILE:0:1}" | tr [a-z] [A-Z]
S
$ echo "${FILE:0:1}" | tr [a-z] [A-Z]
T

El resto del comando simplemente mueve los archivos a su directorio de primera letra correspondiente.

Ejemplo

Digamos que tenemos este directorio de archivos:

$ touch {a-z}file {A-Z}file

$ tree tstdir/ | head -10
tstdir/
|-- afile
|-- Afile
|-- bfile
|-- Bfile
|-- cfile
|-- Cfile
|-- dfile
|-- Dfile
|-- efile
...

Después de ejecutar un trazador de líneas:

$ tree output/ | head -10
output/
|-- A
|   |-- afile
|   `-- Afile
|-- B
|   |-- bfile
|   `-- Bfile
|-- C
|   |-- cfile
|   `-- Cfile
...

Con zsh

mkmv() {mkdir -p -- $argv[-1]:h && mv "[email protected]"}
autoload zmv
zmodload zsh/files

zmv -Qp mkmv '(?)*(^-/)' '${(U)1}/$f'
  • zmv una función para cambiar el nombre de los archivos por lotes de forma segura utilizando los potentes operadores de expansión y coincidencia de patrones de zsh como una función de carga automática.
  • mkmv: una función que actúa como mv excepto que también crea el directorio padre del destino si es necesario.
  • $argv[-1]: $argv igual que $* es la lista de parámetros posicionales, $argv[-1] es el último. Aquí, igual que $3 como zmv lo llama como mkmv -- source destination
  • $var:h: como en csh, obtiene el cabeza de la variable, ese es el nombre del directorio.
  • zmodload zsh/files: carga un módulo que habilita la versión incorporada de algunas utilidades de manejo de archivos que incluyen mkdir y mv, aquí brindando una mejora significativa en el rendimiento, ya que llamamos a ambos para cada archivo.
  • -Q: habilitar desnudo calificadores glob en el patrón. Estos días, otra opción es reescribir (^-/) como (#q^-/).
  • -p mkmv, contar zmv para usar nuestro mkmv funcionar como el programa para hacer el cambio de nombre en lugar de mv
  • (?)*(^-/): un patrón (?)* con un calificador glob utilizado para hacer coincidir los archivos a renombrar. los ? (para que coincida con un solo carácter) entre paréntesis es capturado por lo que puede denominarse $1 en el reemplazo.
  • (^-/): calificadores glob utilizados para hacer coincidir archivos en función de más criterios que solo su nombre:

    • ^: niega los siguientes calificadores
    • -: para los siguientes calificadores, para los enlaces simbólicos, considere el atributo del destino del enlace en lugar del enlace en sí.
    • /: seleccione archivos de tipo directorio. Con los dos calificadores anteriores, eso significa que queremos archivos que no sean directorios ni enlaces simbólicos a directorios.
  • ${(U)1}: el primer carácter capturado del archivo coincidente, convertido a mayúsculas con la U bandera de expansión de parámetros
  • $f en el reemplazo se refiere a la ruta completa del archivo coincidente.

Prueba con este script:

for first in $(ls -1 | sed 's/^(.).*$/1/' | tr '[a-z0-9]' '[A-Z0-9]' | uniq)
do
    mkdir tmp
    mv "$first"* tmp/
    lower=$(echo $first | tr '[A-Z]' '[a-z]')
    mv "$lower"* tmp/
    mv tmp/ "$first";
done

La logica es como sigue:

  1. Enumere todos los archivos del directorio actual.
  2. Extrae el primer carácter con sed.
  3. Cambie el primer carácter a minúsculas con tr, esto es para reducir el número de comparaciones.
  4. Eliminar duplicados con uniq.
  5. Cree un directorio temporal y mueva todos los archivos que comienzan con el personaje a esta carpeta.
  6. Cambie el nombre del archivo temporal.

Usé estos archivos para probar el script:

Apple.txt
avocado.txt
banana.txt
broccoli.txt
car.txt
dddd.txt
delete.txt
zaad.txt
zdfa.txt

Aquí está el resultado:

.
├── A
│   ├── Apple.txt
│   └── avocado.txt
├── B
│   ├── banana.txt
│   └── broccoli.txt
├── C
│   └── car.txt
├── D
│   ├── dddd.txt
│   └── delete.txt
└── Z
    ├── zaad.txt
    └── zdfa.txt

5 directories, 10 files
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *