Comparación de carpetas


10

Tengo dos carpetas con estructuras de subcarpetas similares, que me gustaría comparar. Por ejemplo:

A 
├── child-1
├── child-2
├── child-3
├── child-4
├── child-5

y

B 
├── child-1-some-text
├── child-2-more-text
├── child-3-nothing
├── child-6-random-text
├── child-7-more-random-text

Me gustaría enumerar todas esas subcarpetas de las Acuales son prefijos para una subcarpeta By enumerar también las subcarpetas correspondientes B. La salida esperada es

child-1 -- child-1-some-text
child-2 -- child-2-more-text
child-3 -- child-3-nothing

Un requisito secundario: si hay varias coincidencias B, entonces debería dar un error / advertencia.

Mi solucion :

cd A
for f in `ls -d */`; 
do
    cd B;
    new_dirs=(`ls -1d $f*`);
    cd -;
    if [ ${#new_dirs[@]} -eq 0 ]
    then
        ## DO_Nothing
        continue;
    elif  [ ${#new_dirs[@]} -gt 1 ]
    then
        echo "Multiple matches to $f";
        continue;
    else
        echo "Unique Match found to $f -- ${new_dirs[0]}";
        continue;
    fi;    
done

Problema:

Para aquellos valores de $f, que no tienen subcarpetas correspondientes B, la construcción de la matriz me está dando un error. p.ej:

ls: no se puede acceder a 'child-4 *': no ​​existe tal archivo o directorio

Pregunta

  • ¿Cómo deshacerse de estos errores?
  • ¿Hay una mejor manera de lograr los objetivos que el que está en mi código?

¡Gracias por adelantado!


44
¡+1 por proporcionar una solución casi funcional!
user5325

Esta no es una respuesta a su pregunta específica, pero puede usarla diff -rq DIR1 DIR2para comparar no solo la estructura de directorios, sino también el contenido de los archivos.
jrw32982 es compatible con Monica

Respuestas:


10

La mejor manera

No analizarls ; use globos en su lugar. De hecho, ya estás usando globos, simplemente envolviéndolos ls, lo cual no tiene sentido. Solo necesitas nullglobactivarlo cuando no hay coincidencias.

Evitar también cdsimplifica las cosas.

#!/bin/bash

shopt -s nullglob

dir1=A
dir2=B

for dir in "$dir1"/*/; do
    basename="$(basename -- "$dir")"
    dirs_match=( "$dir2/$basename"*/ )
    case ${#dirs_match[@]} in
    0)
        ;;
    1)
        echo "Unique match for $dir: ${dirs_match[*]}"
        ;;
    *)
        echo "Multiple matches for $dir: ${dirs_match[*]}" >&2
        ;;
    esac
done

Salida:

Unique match for A/child-1/: B/child-1-some-text/
Unique match for A/child-2/: B/child-2-more-text/
Multiple matches for A/child-3/: B/child-3-nothing/ B/child-3-something/

Agregué B/child-3-somethingpara probar el requisito secundario. Esto crea la estructura de directorios para probar:

mkdir -p A/child-{1..5} B/child-{1-some-text,2-more-text,3-nothing,3-something,6-random-text,7-more-random-text}

Por cierto, ShellCheck es muy útil para encontrar problemas en los scripts de shell.


ShellCheck.net es interesante, ¿sabe si carga todo a sus propios servidores o si todo se hace localmente? Solo me pregunto sobre la privacidad de la información ingresada. [Instalar el shellcheckpaquete sería lo más seguro]
Xen2050

@ Xen2050 Intenté desconectar mi Internet mientras estaba en el sitio, y parece que se está cargando. Me imagino que no lo mantiene, pero no estoy seguro. Y sí, el paquete es bueno; Yo uso un complemento Atom que lo usa.
wjandrea

Gracias por las sugerencias Y también muchísimas gracias por apuntar hacia ShellCheck. ¡Me encantó la parte en la que no solo te dice tus errores, sino que también te da sugerencias! @ Xen2050, sobre la parte de carga, acabo de instalar shellcheckusando apty luego deshabilité la red. Parece estar funcionando sin internet .
Mike VDC

2

Llamar lsa una carpeta inexistente arroja el mensaje de error que encontró. La manera más fácil es simplemente ignorar esto mediante la sustitución de la línea 5 en el script con esto: new_dirs=(`ls -1d $f* 2> /dev/null`);.


¿Has probado esto? Stderr parece ser ignorado por defecto, cuando ejecuto t=(`echo ok; echo err 1>&2`)$ t (o ${t[@]}) solo contiene ok, err se ve en la terminal pero no se guarda de todos modos. ¿O hay algo gracioso en mi examen?
Xen2050
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.