User Tag List

Resultados 1 al 8 de 8

Tema: Bash para comparar y renombrar ficheros

  1. #1
    Fecha de ingreso
    Sep 2006
    Mensajes
    4,442
    Agradecer
    545
    Agradecido 477 veces en 354 posts
    Mencionado
    21 Post(s)
    Tagged
    0 Tema(s)

    Question Bash para comparar y renombrar ficheros

    Esto del bash no es lo mio.

    Quiero hacer un script que recorra un directorio, comprima todos los archivos .bin a un par de formatos distintos y renombre a .pak el fichero mas pequeño.

    Creo que las variables name78, name77 y pack no se crean bien, si ponía su valor al final de la parte de compresión funcionaba bien. Ademas que si hago un echo $name78 no imprime nada.

    Gracias.
    Código:
    #!/bin/bash
    
    for file in $(find . -name "*.bin" -type f);
    do
    # nombres terminados en .l78, .l77 y .pak
    	name78 = $(dirname $file)"/"$(basename $file .bin)".l78"
    	name77 = $(dirname $file)"/"$(basename $file .bin)".l77"
    	pak = $(dirname $file)"/"$(basename $file .bin)".pak"
    
    
    # comprime
    lz78 p $file $name78
    	lz77 p $file $name77
    
    
    	size78 = $wc -c < $name78
    	size77 = $wc -c < $name77
    
    
    # renombre a pak el mas pequeño
    if [[ "$size78" -lt "$size77" ]]; then
    		mv $name78 $pak
    else
    		mv $name77 $pak
    fi
    done
    
    
    No es lo mismo tener diez años de experiencia, que tener un año de experiencia diez veces.

  2. #2
    Fecha de ingreso
    Jan 2012
    Mensajes
    380
    Agradecer
    30
    Agradecido 140 veces en 76 posts
    Mencionado
    4 Post(s)
    Tagged
    0 Tema(s)
    Los dos problemas que veo a bote pronto:

    - Al asignar variables el operador "=" no puede ir entre espacios. Variable, operador y valor han de ir juntos.

    - Al tomar el tamaño de los ficheros te olvidaste de los paréntesis de la sustitución de comandos. Es decir, tendría que ser, por ejemplo:

    Código:
    size78=$(wc -c < $name78)
    Corrigiendo eso, el script debería de funcionar para los ficheros y directorios cuyos nombres no contengan espacios. Si hay espacios en los nombres habría que hacerle algunas modificaciones. Por cierto, ¿de dónde salen los comandos lz78 y lz79?

    ----

    El tema de los espacios...

    Dado que el espacio es el separador de campos por defecto, si el resultado de una sustitución puede contener espacios hay que ponerla entre comillas para que el resultado sea un único argumento y no varios. Ejemplo:

    Código:
    $ echo hola > "un fichero.txt"
    $ FILE="un fichero.txt"
    $ cat $FILE
    cat: un: No such file or directory
    cat: fichero.txt: No such file or directory
    $ cat "$FILE"
    hola
    $
    Pero eso no va funcionar con la sustitución del 'for', dado que si la pones entre comillas vas a tener un único argumento formado por el nombre de todos los ficheros. Una solución clásica es hacer una iteración por líneas, en la que cada línea es el nombre de un fichero... Usando una tubería se lee cada línea del listado generado por 'find' y se procesa. Y para generar los nombres de ficheros con la extensión cambiada de forma más "fácil" se puede usar uno de los tipos de expansión de parámetros de bash. Entiendo que los comandos lz78 y lz77 no eliminan el fichero original al comprimirlo.

    Código:
    #!/bin/bash
    
    find . -name "*.bin" -type f |
       while read file; do   
    
          # nombres terminados en .l78, .l77 y .pak
          name78=${file%.bin}.l78
          name77=${file%.bin}.l77
          pak=${file%.bin}.pak
    
          # comprime
          lz78 p "$file" "$name78"
          lz77 p "$file" "$name77"
    
          size78=$(wc -c < "$name78")
          size77=$(wc -c < "$name77")
    
          # renombre a pak el mas pequeño
          if [[ "$size78" -lt "$size77" ]]; then
             mv "$name78" "$pak"
          else
             mv "$name77" "$pak"
          fi
    
       done
    Última edición por Trenz; 28/04/2018 a las 19:37

  3. El siguiente usuario agradece a Trenz este mensaje:

    swapd0 (30/04/2018)

  4. #3
    Fecha de ingreso
    Sep 2006
    Mensajes
    4,442
    Agradecer
    545
    Agradecido 477 veces en 354 posts
    Mencionado
    21 Post(s)
    Tagged
    0 Tema(s)
    Cita Iniciado por Trenz Ver mensaje
    Por cierto, ¿de dónde salen los comandos lz78 y lz77?
    De aqui
    http://s390174849.online.de/ray.tscc.de/code.htm

    Luego miro el resto, ahora estoy en modo weekend.
    No es lo mismo tener diez años de experiencia, que tener un año de experiencia diez veces.

  5. #4
    Fecha de ingreso
    Jan 2012
    Mensajes
    380
    Agradecer
    30
    Agradecido 140 veces en 76 posts
    Mencionado
    4 Post(s)
    Tagged
    0 Tema(s)
    Ah, OK. Era simple curiosidad. Es que me extrañaba un poco porque esos comandos no me sonaban de nada y vi que en Debian al menos no se encontraban en ningún paquete. Y por otro lado, las utilidades clásicas de compresión (gzip y el viejo compress) ya están basadas en esos algoritmos.

    Por cierto, volviendo al script, di por hecho que los ficheros que te interesan están repartidos por un árbol de directorios que cuelga del directorio en el que ejecutas el script, que para eso es útil la búsqueda con 'find'. Porque si no, si están todos en ese mismo directorio, llega con hacer 'for file in *.bin', que es más simple y funciona en todos los casos.

  6. #5
    Fecha de ingreso
    Sep 2006
    Mensajes
    4,442
    Agradecer
    545
    Agradecido 477 veces en 354 posts
    Mencionado
    21 Post(s)
    Tagged
    0 Tema(s)
    Si, es para comprimir los gráficos que hay en una carpeta y dentro de esta hay varios directorios con lo niveles, etc.

    La ventaja es que el código para descomprimir es mínimo, ademas de que lo necesito en ensamblador del 68000
    No es lo mismo tener diez años de experiencia, que tener un año de experiencia diez veces.

  7. #6
    Fecha de ingreso
    Sep 2006
    Mensajes
    4,442
    Agradecer
    545
    Agradecido 477 veces en 354 posts
    Mencionado
    21 Post(s)
    Tagged
    0 Tema(s)
    Gracias

    Ya funciona, lo "raro" es que el 99% de las veces el lz77 comprime mas que el lz78. Así que casi podría comprimir siempre con el mismo, pero vamos ya que esta hecho mejor así y ahorro algunos bytes.
    No es lo mismo tener diez años de experiencia, que tener un año de experiencia diez veces.

  8. #7
    Fecha de ingreso
    Jan 2012
    Mensajes
    380
    Agradecer
    30
    Agradecido 140 veces en 76 posts
    Mencionado
    4 Post(s)
    Tagged
    0 Tema(s)
    Pues no sé... Según la Wikipedia parece que ambos algoritmos son equivalentes:

    They are both theoretically dictionary coders. LZ77 maintains a sliding window during compression. This was later shown to be equivalent to the explicit dictionary constructed by LZ78—however, they are only equivalent when the entire data is intended to be decompressed.
    Gzip y compress implementan los algoritmos Deflate y LZW, los cuales a su vez están basados en LZ77 y LZ78 respectivamente. Gzip comprime bastante más que compress aunque no creo que esto sea directamente extrapolable a LZ77 y LZ78. Gzip es la utilidad de compresión que siempre se ha usado en Linux en lugar de compress (que es la estándar en Unix, estándar POSIX de hecho), aunque esto tiene que ver más con el hecho de que LZW estaba patentado.

  9. #8
    Fecha de ingreso
    Sep 2006
    Mensajes
    4,442
    Agradecer
    545
    Agradecido 477 veces en 354 posts
    Mencionado
    21 Post(s)
    Tagged
    0 Tema(s)
    Ya, digo que es raro porque si miras el código de descompresión el lz77 es muchísimo mas simple XD.

    Tengo que probar el nrv2e que al parecer va bastante bien.
    http://www.oberhumer.com/opensource/ucl/
    No es lo mismo tener diez años de experiencia, que tener un año de experiencia diez veces.

Etiquetas para este tema

Permisos de publicación

  • No puedes crear nuevos temas
  • No puedes responder temas
  • No puedes subir archivos adjuntos
  • No puedes editar tus mensajes
  •