ls -l --group-directories-first (działa również na dowiązania symboliczne)

9

lsopcja --group-directories-firstpowoduje, że katalogi są wyświetlane na górze, co sprawia, że ​​wyjście jest lsładne i czyste:

ls -l --group-directories-first

Jednak to nie działa na symlinks, które są faktycznie symlinksdo katalogów. Istnieje możliwość użycia

ls -l -L --group-directories-first

który wyświetli listę obu rodzajów katalogów na górze, ale nie rozróżni właściwego katalogu i katalogu z dowiązaniem symbolicznym, co znów jest mylące.

Czy lsna górze mogą wyświetlać się dowiązane katalogi, a jednocześnie odróżniać je od zwykłych katalogów?

EDYCJA: Używam bash.

Martin Vegter
źródło
To jest dziwne zachowanie ze strony ls. Zgodnie z stat()wywołaniem systemowym dowiązanie symboliczne do katalogu jest nadal katalogiem ( S_ISDIR(st_mode)zwróci wartość true). Wyraźnie pomija łącza lssymboliczne, zanim to sprawdzi.
goldilocks
2
@goldilocks, no, lsnie lstat()(i readlinkdla dowiązań symbolicznych), chyba że skorzystasz z -Lopcji (w którym to przypadku używa stat())
Stéphane Chazelas 30.01.2014
@StephaneChazelas: Hmm, żyj i ucz się. Myślałem, że to S_ISLNK(st_mode)również zwróciło prawda przez stat(), ale tak nie jest - robi to tylko przez lstat(). Również, że ISLNK nie zwraca true przez stat, nawet jeśli link jest linkiem do linku. Oznacza to, że ISLNKmoże nigdy nie zwróci prawdy poprzez statystyki, chociaż jest to rodzaj nieokreślonego ...
goldilocks 30.01.2014
@goldilocks, statdaje właściwości pliku na końcu dowiązań symbolicznych. Jeśli to nie istnieje lub jest niedostępne, statzwraca ENOENT, więc to, co zostanie zwrócone stat, nigdy nie będzie dowiązaniem symbolicznym. stat()nigdy nie powie ci nic na temat dowiązań symbolicznych, tak jak opennigdy nie otworzy dowiązań symbolicznych, ani chmod()nie zmieni uprawnień dowiązań symbolicznych ... itd.
Stéphane Chazelas

Odpowiedzi:

5

Nie, ale jeśli używasz zsh, możesz:

mll() {
  (($#)) || set -- *(N-/) *(N^-/)
  (($#)) && ls -ldU -- $@
}

Możesz także zdefiniować globalną kolejność sortowania, taką jak:

dir1st() { [[ -d $REPLY ]] && REPLY=1-$REPLY || REPLY=2-$REPLY;}

i używaj go w następujący sposób:

ls -ldU -- *(o+dir1st)

W ten sposób, można ją używać do innych poleceń niż lslub lsz różnymi opcjami, albo dla różnych wzorów, takich jak:

ls -ldU -- .*(o+dir1st) # to list the hidden files and dirs

lub:

ls -ldU -- ^*[[:lower:]]*(o+dir1st) # to list the all-uppercase files and dirs

Jeśli musisz użyć bash, odpowiednik wyglądałby następująco:

mll() (
  if (($# == 0)); then
    dirs=() others=()
    shopt -s nullglob
    for f in *; do
      if [[ -d $f ]]; then
        dirs+=("$f")
      else
        others+=("$f")
      fi
    done
    set -- "${dirs[@]}" "${others[@]}"
  fi
  (($#)) && exec ls -ldU -- "$@"
)

bashnie ma kwalifikatorów globowania ani żadnego sposobu wpływania na porządek sortowania globów, ani żadnego sposobu na zmianę nullglob dla poszczególnych globów, ani też lokalnego kontekstu dla opcji (innych niż uruchomienie podpowłoki, stąd ()zamiast {}wyżej) AFAIK .

Stéphane Chazelas
źródło
1
Czy istnieje jakaś podobna sztuczka bash?
Martin Vegter