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

5

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

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

Por exemplo, uma saída ls -al 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 dois diretórios nessa saída: Public e Sites . O diretório Public não contém subdiretórios, mas Sites faz. Existem 3 subdiretórios em Sites . Portanto, preciso fazer eco apenas dos diretórios que não contêm diretórios. No meu caso, isso é apenas Sites .

    
por Nat Kup 20.03.2013 / 17:31

4 respostas

1

Você não precisa usar awk . Use os testes integrados que o ksh fornece, algo assim:

#!/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 no diretório atual e informa se eles contêm apenas arquivos, nenhum subdiretório.

    
por 20.03.2013 / 17:44
6

Se você é capaz de usar find e se você está trabalhando em um "sistema de arquivos Unix normal" (isto é, como definido em find (1) na descrição da opção -noleaf ), então o seguinte comando pode ser usado:

find . -type d -links 2

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

Então, se você pode usar find , este é indiscutivelmente o método mais rápido e obviamente superior aos loops in-shell sobre o conteúdo do diretório stat() 'em cada um de seus membros.

    
por 18.05.2015 / 05:28
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 faz com que ele se expanda para a lista vazia se não houver correspondência. Sem isso, o padrão permanece inalterado se não houver correspondência.

A seguinte função ksh93 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
    
por 21.03.2013 / 02:01
0

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

find . -type f

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

Espero que seja isso o que você está procurando

    
por 20.03.2013 / 17:44