enumera todos los directorios que contienen archivos *.html y también enumera los archivos en los directorios

enumera todos los directorios que contienen archivos *.html y también enumera los archivos en los directorios

Me gustaría obtener la lista de todos los directorios que contienen documentos HTML, terminados .htmo .htmlignorando mayúsculas o minúsculas.

Yo he tratado:

find / -type d -ls | tr -s [:blank:] | cut -d ' ' -f 11 | grep -i -e "*.htm" -e "*.html"

Pero solo enumera directorios, y necesito enumerar el contenido de esos directorios y no sé cómo.

Luego lo intenté:

find / -type d -exec ls -l {} \; | tr -s [:blank:] | cut -d ' ' -f 9 | grep -i -e ".htm" -e ".html"

Y sí los encuentra, pero ¿cómo imprimo los directorios donde están?

Respuesta1

A continuación se muestran algunos comandos posibles, incluida una salida de ejemplo.

Lo más sencillo:

$ find / -iname "*.htm*"
foo/a.HTM
foo/b.HTML
foo/b.html
foo/x.htmx
foo/a.htm
bar/a.htm

-inamesignifica encontrar archivos que coincidan con glob y no distinguir entre mayúsculas y minúsculas. El problema es que el globo *.htm*también lo encuentra htmx.

Para evitar que lo encuentren, htmxdebe dividir el globo:

$ find / -iname "*.htm" -o -iname "*.html"
foo/a.HTM
foo/b.HTML
foo/b.html
foo/a.htm
bar/a.htm

O use grep que puede usar expresiones regulares:

$ find / | grep -i "\.html*$"
foo/a.HTM
foo/b.HTML
foo/b.html
foo/a.htm
bar/a.htm

Tenga en cuenta que la expresión regular es diferente a glob. Especialmente el punto ( .) y la estrella ( *) tienen significados muy diferentes en glob y regex.

Verhttps://en.wikipedia.org/wiki/Glob_(programming)#Compared_to_regular_expressionspara más información.

Respuesta2

Usando zsh:

setopt extendedglob nullglob
for pathname in /**/*(/e{'[[ -n $REPLY/(#i)*.htm(l#)(#q.) ]]'}); do
    printf '%s:\n' $pathname
    ls -l $pathname
done

Esto imprime el nombre de ruta de cada directorio que contiene cualquier archivo normal cuyo nombre termine con .htmo .html(independientemente del caso), seguido de la ls -lsalida de ese directorio.

El bucle recorre cada directorio dentro o debajo /que contiene un archivo HTML. Lo hace utilizando el /**/*globo que, por sí solo, coincide con todo en toda la /jerarquía de directorios. Esta lista se filtra para que solo contenga nombres de rutas de directorio mediante el /calificador global (la inicial /en el primer paréntesis), y la lista se filtra aún más para contener solo aquellas entradas que [[ -n $REPLY/(#i)*.htm(l#)(#q.) ]]son verdaderas. Esta expresión, donde $REPLYse encuentra uno de los nombres de ruta del directorio que se examinan, será verdadera si un directorio contiene al menos un archivo normal con un sufijo de nombre de archivo .htmo .html(sin distinguir entre mayúsculas y minúsculas).

La e{...}parte del patrón globular probablemente podría escribirse de manera más sucinta.


Usando bash:

shopt -s globstar nullglob extglob nocaseglob
for pathname in /**/*/; do
    set -- "$pathname"/*.htm?(l)
    if [[ -f $1 ]]; then
        printf '%s:\n' "${pathname%/}"
        ls -l "$pathname"
    fi
done

Esto utiliza la globstaropción de shell para habilitar el uso del **patrón global (habilitado de forma predeterminada en el zshshell). Itera sobre todos los nombres de rutas de directorio en toda la jerarquía de directorios desde /abajo e intenta expandir el *.htm?(l)global en cada directorio (esto coincide con los archivos HTML que nos interesan). Si la primera coincidencia de este globo es un archivo normal, o un enlace simbólico a uno, entonces ls -lse genera el nombre de la ruta del directorio y el listado.

Si es posible que tengasdirectorioscon el sufijo .htmon .htmlfilename, tendrías que probar las coincidencias de la expansión dentro del bucle en un bucle separado, solo para asegurarte de capturar cualquier archivo normal (o enlaces simbólicos a archivos normales) con los sufijos HTML:

shopt -s globstar extglob nocaseglob
for pathname in /**/*/; do
    for match in "$pathname"/*.htm?(l); do
        if [[ -f $match ]]; then
            printf '%s:\n' "${pathname%/}"
            ls -l "$pathname"
            break
        fi
    done
done

Eliminé la nullglobopción Shell en esta variación porque ya no dependemos de ella.


En el shshell POSIX no tienes acceso al **glob, por lo que tendrías que usarlo findpara generar los nombres de ruta del directorio para el bucle:

find / -type d -exec sh -c '
    for pathname do
        for match in "$pathname"/*.[hH][tT][mM] "$pathname"/*.[hH][tT][mM][lL] ; do
            if [ -f "$match" ]; then
                printf "%s:\n" "${pathname%/}"
                ls -l "$pathname"
                break
            fi
        done
    done' sh {} +

Aquí, findactúa como una especie de generador de nombres de rutas para el sh -cscript incrustado y lo alimenta con nombres de rutas de directorios.

El sh -cscript hace más o menos lo que bashhace la segunda variación de la respuesta, es decir, itera sobre la expansión del globo que debería coincidir con los nombres deseados, probando cada nombre para ver si es un archivo normal (o un enlace simbólico a uno). Una vez que encuentra un archivo, imprime el nombre de la ruta del directorio seguido de la ls -lsalida.

Respuesta3

Yo sugeriría usar

find / '(' -iname '*.htm' -o -iname '*.html' ')' -printf '%h\n' | uniq | xargs -r -d '\n' ls -l

La primera parte, find / '(' -iname '*.htm' -o -iname '*.html' ')' -printf '%h\n'busca todos los archivos que terminan en .htmmayúsculas .htmlo minúsculas (usando patrones globales) e imprime el directorio ( %h) para cada archivo encontrado, un directorio por línea.

Debido a la forma en que findescanea los directorios, se enumeran uno o más directorios idénticos consecutivos; uniqconserva sólo uno de cada uno.

Finalmente, le enviamos la lista de directorios xargs, diciéndole que no ejecute un comando sin ningún directorio -ry que el separador sea una nueva línea -d '\n'. El comando es ls -l; modifica a tu gusto.

Si solo necesita la lista de directorios, no el contenido de esos directorios, elimine la xargsparte:

find / '(' -iname '*.htm' -o -iname '*.html' ')' -printf '%h\n' | uniq

información relacionada