Použijte GNU si můžete zobrazit pouze ty list adresáře

hlasů
34

Snažím se používat GNU najít najít pouze adresáře, které neobsahují žádné další adresáře, ale může nebo nemusí obsahovat běžné soubory.

Můj nejlepší odhad doposud byl:

find dir -type d \( -not -exec ls -dA ';' \)

ale to mi prostě dostane dlouhý seznam „“

Dík!

Položena 24/11/2010 v 18:40
zdroj uživatelem
V jiných jazycích...                            


6 odpovědí

hlasů
61

Můžete použít -links pokud váš souborový systém je POSIX kompatibilní (tj adresář má vazbu pro každý podadresář v něm, v odkazu z jeho mateřské společnosti a odkazem na sebe, což je počet 2, odkaz, pokud to má žádné podadresáře).

Následující příkaz by měl dělat to, co chcete:

find dir -type d -links 2

Nicméně, to nezdá pracovat na systému Mac OS X (jako @Piotr zmíněna). Zde je další verze, která je pomalejší, ale funguje na Mac OS X. Je založen na jeho verzi, s korekcí zvládnout mezery v názvy adresářů:

find . -type d -exec sh -c '(ls -p "{}"|grep />/dev/null)||echo "{}"' \;
Odpovězeno 24/11/2010 v 18:46
zdroj uživatelem

hlasů
1

@Sylvian řešení nepracoval pro mě na Mac OS X z nějakého podivného důvodu. Tak jsem přišel s trochu více přímé řešení. Doufám, že to pomůže někdo:

find . -type d  -print0 | xargs -0 -IXXX sh -c '(ls -p XXX | grep / >/dev/null) || echo XXX' ;

Vysvětlení:

  • ls -p končí adresářů s ‚/‘
  • tak (ls -p XXX | grep / >/dev/null)vrací 0, pokud neexistuje žádná adresáře
  • -print0&& -0je, aby xargs zpracovat mezery v názvy adresářů
Odpovězeno 28/04/2011 v 16:05
zdroj uživatelem

hlasů
0

Mám nějaké zvláštně pojmenované soubory ve svých adresářových stromů, které matou awkjako v @AhmetAlpBalkan ‚s odpovědí. A tak jsem si vzal trochu jiný přístup

  p=;
  while read c;
    do 
      l=${#c};
      f=${p:0:$l};
      if [ "$f" != "$c" ]; then 
        echo $c; 
      fi;
      p=$c; 
    done < <(find . -type d | sort -r) 

Stejně jako v awkroztoku, to v obráceném. Tak v případě, že cesta k adresáři je podcestou předchozí hit, můžete snadno rozpoznat to.

Tady pje můj předchozí zápas, cje současný zápas, lje délka aktuálního zápasu, fje první lodpovídající znaky z předchozího utkání. I jen echoty zásahy, které neodpovídají na začátek předchozího utkání.

Problém s awknabízeného řešení je to, že shoda na začátku řetězce se zdá být zmatené, pokud cesta obsahuje věci, jako +ve jménu některé z podadresáře. To způsobilo, že awkse vrátí počet falešných pozitiv pro mě.

Odpovězeno 23/09/2018 v 16:07
zdroj uživatelem

hlasů
0

Právě jsem našel další řešení tohoto problému, který pracuje jak na Linuxu a MacOS (bez find -exec)!

Jedná se sort(dvakrát) a awk:

find dir -type d | sort -r | awk 'a!~"^"$0{a=$0;print}' | sort

Vysvětlení:

  1. třídit findvýstup v opačném pořadí

    • Nyní máte podadresáře se objeví jako první, pak jejich rodiče
  2. pouze awkvynechat linky, pokud je aktuální řádek předpona předchozího řádku

    • (tento příkaz je z odpovědi zde )
    • Nyní máte odstraněny „všechny nadřazené adresáře“ (jste odešel s mateřskými dirs)
  3. sortje (takže to vypadá jako normální findvýstup)
  4. Voila! Rychlý a přenosný.
Odpovězeno 27/05/2018 v 03:59
zdroj uživatelem

hlasů
0

Zde je řešení, které funguje na systému Linux a OS X:

find . -type d -execdir bash -c '[ "$(find {} -mindepth 1 -type d)" ] || echo $PWD/{}' \; 

nebo:

find . -type d -execdir sh -c 'test -z "$(find "{}" -mindepth 1 -type d)" && echo $PWD/{}' \;
Odpovězeno 23/09/2015 v 13:47
zdroj uživatelem

hlasů
0

Co tenhle ? Je přenosný a nezáleží na finnicky spojujících bodech. Všimněte si však, že je důležité, aby root/folder bez vlečného /.

find root/folder -type d | awk '{ if (length($0)<length(prev) || substr($0,1,length(prev))!=prev) print prev; prev=($0 "/") } END { print prev }'
Odpovězeno 04/09/2015 v 03:06
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more