Buscar directorios que no contienen subdirectorios

10

Estoy escribiendo guión es ksh. Necesita encontrar todos los nombres de directorio directamente debajo del directorio actual que contienen solo archivos, no subdirectorios.

Sé que podría usar ls -alRy analizar de forma recursiva la salida de la primera letra en el primer campo ( dpara un directorio). Creo que awkes la mejor manera de analizar y encontrar.

Por ejemplo, una ls -alsalida simple en el directorio actual:

   drwxr-xr-x  22 af      staff    748 18 Mar 22:21 .
   drwxr-xr-x   5 root    admin    170 17 Mar 18:03 ..
   -rw-------   1 af      staff      3 17 Mar 16:37 .CFUserTextEncoding
   drwxr-xr-x   5 af      staff    170 17 Mar 17:12 Public
   drwxr-xr-x   9 af      staff    306 18 Mar 17:40 Sites
   -rw-------   1 af      staff      3 17 Mar 16:37 textd
   

Hay 2 directorios en esta salida: Publicy Sites. El directorio Publicno contiene subdirectorios, pero Sitessí. Hay 3 subdirectorios en Sites. Por lo tanto, necesito hacer eco solo de los directorios que no contienen directorios en ellos. En mi caso, esto es solo Sites.

Nat Kup
fuente

Respuestas:

1

No necesita usar awken absoluto. Utilice las pruebas integradas que kshproporciona, algo como esto:

#!/bin/ksh

for NAME in *
do
    FOUND=no
    if [[ -d $NAME && $NAME != '.' && $NAME != '..' ]]
    then
        for SUBNAME in $NAME/*
        do
            if [[ -d $SUBNAME ]]
            then
                FOUND=yes
                break
            fi
        done
        if [[ $FOUND == no ]]
        then
            echo Found only files in $NAME
        fi
    fi
done

Ese pequeño script busca en todos los directorios en el directorio actual y le dice si solo contienen archivos, no subdirectorios.

Bruce Ediger
fuente
14

Si puede usar findy está trabajando en un "sistema de archivos Unix normal" (es decir, como se define en find (1) en la descripción de la opción -noleaf ), se puede usar el siguiente comando:

find . -type d -links 2

Cada directorio tiene al menos 2 nombres (enlaces duros): .y su nombre. Sus subdirectorios, si los hay, apuntarán ..al directorio principal, por lo que un directorio con N subdirectorios tendrá un recuento de enlaces rígidos igual a N + 2. Por lo tanto, al buscar directorios con un recuento de enlaces duros igual a 2, buscamos directorios con subdirectorios N = 0.

Entonces, si puede usar find, este es posiblemente el método más rápido y obviamente superior a los bucles en shell sobre el contenido del directorio stat()de cada uno de sus miembros.

intelfx
fuente
Esto no parece funcionar si el directorio contiene algún archivo.
user394
1
No se trata de entradas en la lista del directorio, se trata de enlaces duros que se refieren al inodo del directorio. Por ejemplo, si /some/directorytiene el inodo # 12345678, si no tiene subdirectorios, habrá exactamente 2 enlaces duros a ese inodo: /some/directory/.y /some/directory. Funciona si hay o no archivos en el directorio.
telcoM
Vale la pena mencionar que BTRFS no es un "sistema de archivos Unix normal" a este respecto: desafortunadamente, los directorios siempre tienen un conteo de enlaces de 1. (Pero .y foo/..tengo el mismo número de inodo.)
Peter Cordes
3

*/coincide con los subdirectorios del directorio actual. Esto incluye enlaces simbólicos a directorios, que puede desear o no.

En ksh93, agregar ~(N)al comienzo del patrón hace que se expanda a la lista vacía si no hay coincidencia. Sin esto, el patrón permanece sin cambios si no hay coincidencia.

La siguiente función ksh93 enumera los subdirectorios de los directorios actuales que no contienen ningún subdirectorio o enlace a un directorio.

list_leaf_directories () {
  local FIGNORE='.?(.)'        # don't ignore dot files
  local d
  for d in */; do
    [[ -L $d ]] || continue;   # skip symbolic links
    set -- ~(N)"$d"/*/
    if ((!$#)); then echo "$d"; fi
  done
done
Gilles 'SO- deja de ser malvado'
fuente
0

si no te estoy malentendiendo, solo quieres encontrar archivos en el directorio, no en los subdirectorios. Si esta es tu intención, aquí está la solución

find . -type f

si desea buscar archivos que no sean normales (como archivos de dispositivo de bloque, archivos de dispositivo de caracteres, etc.), consulte la página del findcomando man y busque la palabra clave type en esa página. Verá diferentes tipos de archivos, incluidos archivos y directorios normales, etc.

Espero que esto sea lo que buscas

MelBurslan
fuente
No, esa no es la pregunta en absoluto. Está razonablemente claro una vez que s / catalog / directory / g. Nat Kup está buscando directorios que no contengan subdirectorios.
Gilles 'SO- deja de ser malvado'