¿Por qué mi script de bash shell cambia los espacios a saltos de línea?

¿Por qué mi script de bash shell cambia los espacios a saltos de línea?

Comencé escribiendo un script de shell bash simple para encontrar archivos duplicados dentro de un directorio determinado usando SHA1 para detectar coincidencias. Todo funcionó hasta que encontré nombres de archivos con espacios. La detección todavía funciona, pero en la salida los espacios se convierten en avances de línea.

La secuencia de comandos...

#!/bin/bash
export TARGET=$1
find $TARGET -type f -exec openssl sha1 \{\} \; > ./dupes.txt
COUNT=-1
for EVALUATION in `cat ./dupes.txt | sed 's/SHA1(\(.*\))\= \(.*\)$/\2 \1/' | awk '{print $1}' | sort | uniq -c | sort -nr`
do
    if [[ $COUNT == -1 ]]
    then
        COUNT=$EVALUATION
    else 
        HASH=$EVALUATION
        if [[ $COUNT == 1 ]]
        then
            break
        fi
        echo "--- duplicate set ---"
        for FILE in `grep $HASH ./dupes.txt | awk -F"[()]+" '{print $2}'`
        do
            echo "$FILE"
        done
        echo "---------------------"
        COUNT=-1
    fi
done

Ejecute el script como...

./dupes.sh /home/dacracot/testDupes

Creará un archivo dupes.txt que se parece a...

SHA1(/home/dacracot/testDupes/lP3wj.jpg)= 324d91f412745481ed38aa184e5a56bfc3bf43b5
SHA1(/home/dacracot/testDupes/1673.gif)= 9c4029ec2e310f202b413d685209373d234e5465
SHA1(/home/dacracot/testDupes/.DS_Store)= b0ae6631a1412863f958da64091f4050005bf8d6
SHA1(/home/dacracot/testDupes/tae 2.svg)= 3ddc4fd6ae505bd01f370d0a018ef1f84b4d8011
SHA1(/home/dacracot/testDupes/tae.graffle)= 77f1ad6d695d944abacfe3a7f196be77125b6ef6
SHA1(/home/dacracot/testDupes/tae.svg)= 3ddc4fd6ae505bd01f370d0a018ef1f84b4d8011
SHA1(/home/dacracot/testDupes/22402_graph.jpg)= 24e5a25c8abf322d424dd5ce2e5b77381cd001c4
SHA1(/home/dacracot/testDupes/forwardcont.jpg)= 981e75060ae8e3aad2fe741b944d97219c8ccbe5
SHA1(/home/dacracot/testDupes/tae.svg.gz)= 922af5a5adbf7a4e7fd234aac7bcee2986133c4d
SHA1(/home/dacracot/testDupes/Alt2012.pdf)= 97d1fd997df9eb310b30a371c53883f5227cf10a
SHA1(/home/dacracot/testDupes/vcBZ8.jpg)= 7553c19fcb6aa159aada2e38066b5ba84465ee57
SHA1(/home/dacracot/testDupes/derm.graffle)= 0e1c4032f5f1fadc3a1643b2b77f816011c2d67f
SHA1(/home/dacracot/testDupes/WA.png)= 0e2e77624c3a76da4816f116665a041f6bdced2d
SHA1(/home/dacracot/testDupes/DRAW.GIF)= 6a8e4a2bf413e84140a0edeb40b475a5d3e4c255
SHA1(/home/dacracot/testDupes/crazyTalk.gif)= 1d938bbcb8cf09f30492df4504a50348cef7ea9d

Y finalmente un resultado que se parece a...

--- duplicate set ---
/home/dacracot/testDupes/tae
2.svg
/home/dacracot/testDupes/tae.svg
---------------------

Pero como puede ver en el primer archivo, el resultado debería ser...

--- duplicate set ---
/home/dacracot/testDupes/tae 2.svg
/home/dacracot/testDupes/tae.svg
---------------------

¿Qué es cambiar el espacio a un salto de línea?

Respuesta1

¿Puedo hacer algunas modificaciones a su script para simplificarlo y también eliminar su problema?

Veo que está utilizando OpenSSL para calcular el hash SHA1 y luego analiza algunos resultados innecesarios y procede a ordenar e iterar sobre la lista de hashes. No especificas una etiqueta de sistema operativo en tu publicación, pero tu uso /bin/bashsugiere Linux, así que ¿por qué no usarla sha1sumen su lugar? Produce una salida más simple que es más fácil de procesar para su script. (Los lectores que utilizan BSD pueden utilizarlo sha1 -rpara obtener resultados equivalentes).

#!/bin/bash

find "$1" -type f -exec sha1sum \{\} \; > dupes.txt

awk '{print $1}' < dupes.txt |
  sort | uniq -c | sort -nr |
  while read COUNT HASH; do
    if [[ $COUNT == 1 ]]; then
      break
    else
      echo "--- duplicate set ---"
      grep "^$HASH " dupes.txt | sed -e "s/[^ ]* //"
      echo "---------------------"
    fi
  done

Se pueden realizar más optimizaciones, como usar findla -print0opción y xargs, pero esperamos que las revisiones anteriores le ayuden a empezar.

información relacionada