Encontre diretórios que não contêm subdiretórios

10

Estou escrevendo script é ksh. Precisa encontrar todos os nomes de diretório diretamente no diretório atual, que contêm apenas arquivos, não subdiretórios.

Eu sei que eu poderia usar ls -alRe analisar recursivamente a saída para a primeira letra no primeiro campo ( dpara um diretório). Eu acho que awké a melhor maneira de analisar e encontrar.

Por exemplo, uma ls -alsaída simples no diretório atual:

   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
   

Existem 2 diretórios nesta saída: Publice Sites. O diretório Publicnão contém subdiretórios, mas contém Sites. Existem 3 subdiretórios em Sites. Então, eu preciso ecoar apenas os diretórios que não contêm diretórios neles. No meu caso, isso é apenas Sites.

Nat Kup
fonte

Respostas:

1

Você não precisa usar awknada. Use os testes internos que kshfornecem, algo como isto:

#!/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

Esse pequeno script procura em todos os diretórios do diretório atual e informa se eles contêm apenas arquivos, sem subdiretórios.

Bruce Ediger
fonte
14

Se você puder usar finde se estiver trabalhando em um "sistema de arquivos Unix normal" (ou seja, conforme definido em find (1) em -noleaf option description), o seguinte comando poderá ser usado:

find . -type d -links 2

Cada diretório possui pelo menos 2 nomes (links físicos): .e seu nome. Seus subdiretórios, se houver, terão um ..apontador para o diretório pai, portanto, um diretório com N subdiretórios terá uma contagem de links físicos igual a N + 2. Assim, procurando diretórios com contagem de links físicos igual a 2, procuramos diretórios com subdiretórios N = 0.

Portanto, se você pode usar find, esse é sem dúvida o método mais rápido e obviamente superior aos loops no shell sobre o conteúdo do diretório em stat()cada um de seus membros.

intelfx
fonte
Isso não parece funcionar se o diretório contiver algum arquivo.
user394
1
Não se trata de entradas na lista de diretórios, mas de links físicos referentes ao inode do diretório. Por exemplo, se /some/directorytiver o inode # 12345678, se não houver subdiretórios, haverá exatamente 2 links físicos para esse inode: /some/directory/.e /some/directory. Funciona se há ou não arquivos no diretório.
telcoM 28/01/19
Vale ressaltar que o BTRFS não é um "sistema de arquivos Unix normal" a esse respeito: os diretórios sempre têm uma contagem de links 1, infelizmente. (Mas .e foo/..têm o mesmo número de inode.)
Peter Cordes
3

*/corresponde aos subdiretórios do diretório atual. Isso inclui links simbólicos para diretórios, que você pode ou não desejar.

No ksh93, adicionar ~(N)no início do padrão o expande para a lista vazia se não houver correspondência. Sem isso, o padrão permanece inalterado se não houver correspondência.

A função ksh93 a seguir lista os subdiretórios dos diretórios atuais que não contêm nenhum subdiretório ou link para um diretório.

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- parar de ser mau'
fonte
0

se não estou lhe entendendo mal, você só deseja encontrar arquivos no diretório e não nos subdiretórios. Se essa é a sua intenção, aqui está a solução

find . -type f

se você quiser encontrar outros arquivos que não sejam regulares (como arquivos de dispositivos de bloco, arquivos de dispositivos de caracteres etc.), consulte a página de manual do findcomando e procure a palavra-chave type nessa página. Você verá diferentes tipos de arquivos, incluindo arquivos e diretórios regulares, etc.

Espero que seja isso que você está procurando

MelBurslan
fonte
Não, essa não é a questão. É razoavelmente claro quando você s / catalog / directory / g. Nat Kup está procurando diretórios que não contêm subdiretórios.
Gilles 'SO- stop being evil'