Як сортувати перші каталоги, а потім файли тощо ... при використанні “ls” в Unix


91

Я хотів би скористатися lsкомандою, щоб спочатку показати каталоги, а потім файли. Я намагався:

ls -la | sort -k 1

Але я отримав неправильне замовлення.


це тому, що -йде раніше, ніж dвикористовуватиsort
Nifle

4
Старі заголовки Unix (ті, що знаходяться в епоху до GUI), використовувались для використання великих імен папок і для отримання імен звичайних файлів, не написаних великими літерами, щоб отримати результат автоматично.
Дж. Роберт

Корисне запитання! Можливо, настав час змінити прийняту відповідь на ту, яка простіша і не порушує термінальні кольори?
ippi

Спробуйтеls -lh --group-directories-first
Діого

Відповіді:


28

Наступна команда перелічить каталоги по-перше, звичайні файли - друге, а посилання - треті.

ls -la | grep "^d" && ls -la | grep "^-" && ls -la | grep "^l"

Крім того, було б багато сенсу створити псевдонім для цієї команди, щоб зберегти натискання клавіш.

Редагувати:

Якщо ви хочете спочатку каталоги, а потім все, що не є каталогом, скористайтеся цим:

ls -la | grep "^d" && ls -la | grep -v "^d"


1
Ця команда не перераховує все, якщо в папці є, наприклад, сокети або FIFO
Studer

1
Ця відредагована версія все ще повинна працювати з іншими типами. Перший греп каже все, що починається з 'd', а другий говорить все, що не починається з 'd'. Напевно, все або починається з реклами, або ні, правда?
Bra4 Ry4an Brase

1
@Mark - Чому б просто не зробити ls -la | grep "^d" && ls -la | grep "^-" && ls -la | grep -v -E "^d|^-|^total":?
FCTW

1
Щоб команда @ FCTW стала псевдонімом OSX, додайте це до свого ~ / .profile:alias la="ls -la | grep \"^d\" && ls -la | grep \"^-\" && ls -la | grep -E \"^d|^-\" -v | grep -v \"^total\""
aliteralmind

2
Я знайшов працююче коротше позначення: ls -la|grep ^d;ls -la|grep -v ^d(лапки не потрібні та замінені &&на ;). Іншим варіантом є введення змінної , а потім оцінити його: a="ls -la|grep ^d";eval $a;eval $a -v. Може бути корисним, щоб уникнути повторів, коли ls/ задано набагато більше варіантів grep. Є і такий ls -la --group-directories-firstваріант, проте найкоротший ls -la|sort
імідж

204

Я так люблю * nix і люблю бачити винахідливість, яка входить в деякі з цих відповідей ...

У GNU Linux шахта не настільки фантазія:

alias ls='ls --color -h --group-directories-first'

Зважаючи на те, що мені зручніше з моїми програмами CLI для Linux, я також оновлюю основні програми на OSX:

brew install coreutils
alias ls='/usr/local/bin/gls --color -h --group-directories-first'

6
на жаль, це не працює на osx-терміналі, оскільки - опція недоступна.
MEM

7
re love: Це сарказм? Якщо так, я погодився б.
allyourcode

4
Призначення псевдоніма ls полягає у визначенні елементів конфігурації, які я хочу використовувати 90% часу. Менше натискань клавіш для досягнення бажаного результату. Якщо ви коли-небудь хочете мати вихідний ls вихід, ви завжди можете / bin / ls.
jonathanserafini

4
@MEM Якщо ви використовуєте OS X і вам подобається користуватися терміналом, вам слід brew install bash , це спрацює! :)
Ендрю Ашбахер

5
Моя думка: ця відповідь повинна була бути прийнятою, оскільки в ній вказаний варіант командного рядка для досягнення точно поставленої мети, а не перекрученого набору грепів тощо.
Райан Гріггс

17

Основні програми для користувачів Mac :

brew install coreutils

alias ls='ls --color -h --group-directories-first'

Якщо припустити, що ваша система готова до домашнього приготування :


7
glsскоріше. Правильно?
Пол Ірландський

1
Так, за замовчуванням. Ви також можете використовувати coreutils за замовчуванням з PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH".
benesch

7

У списку каталогів я хочу бачити певні речі, і поки жодна відповідь не відповідає всім вимогам, наведеним нижче. Мої вимоги до переліку каталогів:

  1. Каталоги та файли сортуються за алфавітом
  2. Каталоги перераховані першими
  3. Символічні посилання (символьні посилання) сортуються як файли
  4. Сортування відмінне від регістру
  5. Сортування ігнорує всі провідні символи, що не належать до альфа, у імені файлу
  6. Лістинг включає загальну кількість каталогів (крім ./і ../), файлів та посилань
  7. Лістинг включає загальний розмір (використання диска) каталогів та файлів
  8. Цей список повинен виглядати однаково на Linux та Windows (оболонка Git Bash) - це було найскладніше правильно, оскільки зручні варіанти, як --group-directories-firstне працює в Git Bash для Windows

Після довгого злому я нарешті придумав однолінійку (хоч і дуже довгу лінію ;-)), якою я задоволений. Я призначив цей псевдонім на ім’я "dir":

ls -dlF --color * .* | head -n2 && ls -AlF | LC_ALL=C grep "^d" | 
LC_ALL=C sort -k 9df && ls -AlF | LC_ALL=C grep "^[l-]" | 
LC_ALL=C sort -k 9df && echo -e `find -maxdepth 1 -type d ! -name . | 
wc -l` Dir\(s\) `du -hs | cut -f 1`\\t\\t`find -maxdepth 1 -type f | 
wc -l` File\(s\) `find -maxdepth 1 -type f -print0 | du -ch --files0-from=- | 
tail -n 1 | cut -f 1`\\t\\t`find -maxdepth 1 -type l | wc -l` Link\(s\)

Щоб полегшити управління, я придумав окремі команди для виведення кожного сегмента списку каталогів на свій смак, а потім зібрав їх разом за допомогою &&оператора.

  • ls -dlF --color * .* | head -n2- Витяг ./і ../. Ми не хочемо їх передавати через те, sortщо вони вже в правильному порядку, і сортування їх може призвести до ../того, що вони будуть вперше вказані у списку. -dВаріант , щоб позбутися від «повної» лінії; Мені подобається додати, -Fщоб показати прорізну косу рису для каталогів (вона також позначатиме символьні посилання символом "@", коли ви робите звичайну ls -F).

  • ls -AlF | LC_ALL=C grep "^d" | LC_ALL=C sort -k 9df- Витягніть каталоги та сортуйте їх за назвою файлів (9-й стовпець), ігноруючи як не-альфа / пробіли символів ( dопція), так і регістр символів ( fопція). Цей ls -Aпараметр виключає ./і ../з лістингу, оскільки ми вже вилучили їх на попередньому кроці. Я схильний до префіксації всіх grepта sortкоманд із LC_ALL=Cскиданням локалі, щоб (1) вихід був узгодженим через оболонки Unix, і (2) іноді ви можете бачити більш високу продуктивність, оскільки у нього більше немає накладних витрат важкого символу UTF-8 мати справу з.

  • ls -AlF | LC_ALL=C grep "^[l-]" | LC_ALL=C sort -k 9df - Це схоже на крок вище, але цього разу ми сортуємо файли та посилання.

  • find -maxdepth 1 -type d ! -name . | wc -l- Отримайте кількість каталогів, виключаючи ./та ../.

  • find -maxdepth 1 -type f | wc -l - Отримайте кількість файлів.

  • find -maxdepth 1 -type l | wc -l - Отримайте кількість посилань.

  • du -hs | cut -f 1 - Витягніть загальний розмір усіх підкаталогів у читаному для людини форматі.

  • find -maxdepth 1 -type f -print0 | du -ch --files0-from=- | tail -n 1 | cut -f 1 - Витягніть загальний розмір усіх файлів у читаному для людини форматі.

Побачимо наш новий dirпсевдонім у дії!

ПЕРЕД:

$ ls -alF
total 22
drwxr-xr-x   13 Tom      Administ     4096 Oct 25 02:38 ./
drwxr-xr-x    3 Tom      Administ        0 Dec 24  2014 ../
drwxr-xr-x   15 Tom      Administ     4096 Sep 17 01:23 .VirtualBox/
-rw-r--r--    1 Tom      Administ      615 Oct 25 02:38 .aliases
-rw-r--r--    1 Tom      Administ    12742 Oct 24 11:47 .bash_history
-rw-r--r--    1 Tom      Administ     3234 Oct 24 15:06 .bash_profile
drwxr-xr-x    1 Tom      Administ        0 Jan 24  2015 .gem/
-rw-r--r--    1 Tom      Administ      586 Oct 24 03:53 .gitconfig
drwxr-xr-x    1 Tom      Administ     4096 Dec 28  2014 .ssh/
drwxr-xr-x    4 Tom      Administ        0 Jan 24  2015 .travis/
-rw-r--r--    1 Tom      Administ     6645 Oct 25 02:38 _viminfo
-rw-r--r--    1 Tom      Administ     4907 Oct 24 15:16 profile
drwxr-xr-x    1 Tom      Administ        0 Oct 24 22:20 tmp/

ПІСЛЯ:

$ dir
drwxr-xr-x   13 Tom      Administ     4096 Oct 25 02:38 ./
drwxr-xr-x    3 Tom      Administ        0 Dec 24  2014 ../
drwxr-xr-x    1 Tom      Administ        0 Jan 24  2015 .gem/
drwxr-xr-x    1 Tom      Administ     4096 Dec 28  2014 .ssh/
drwxr-xr-x    1 Tom      Administ        0 Oct 24 22:20 tmp/
drwxr-xr-x    4 Tom      Administ        0 Jan 24  2015 .travis/
drwxr-xr-x   15 Tom      Administ     4096 Sep 17 01:23 .VirtualBox/
-rw-r--r--    1 Tom      Administ      615 Oct 25 02:38 .aliases
-rw-r--r--    1 Tom      Administ    12742 Oct 24 11:47 .bash_history
-rw-r--r--    1 Tom      Administ     3234 Oct 24 15:06 .bash_profile
-rw-r--r--    1 Tom      Administ      586 Oct 24 03:53 .gitconfig
-rw-r--r--    1 Tom      Administ     4907 Oct 24 15:16 profile
-rw-r--r--    1 Tom      Administ     6645 Oct 25 02:38 _viminfo
      5 Dir(s) 2.8M           6 File(s) 31K           0 Link(s)

Невеликим недоліком є ​​те, що ви не можете мати кольорові списки, оскільки символи керування кольором, що оточують імена файлів, роблять сортування занадто недостовірним.


ОНОВЛЕННЯ

Псевдонім вище був болісно повільним при виконанні з кореневого каталогу глибокої файлової системи, тому я оновив до цієї простішої, але набагато ефективнішої команди:

ls -AFoqv --color --group-directories-first | tail -n +2 && find -maxdepth 1 -type f -printf '%s\n' | awk '{total+=$1} END {print total" bytes"}'

Вибірка зразка:

$ dir
drwxr-xr-x 1 Tom     0 Mar 29 13:49 .aws/
drwxr-xr-x 1 Tom     0 Mar 29 13:49 .gem/
drwxr-xr-x 1 Tom     0 Mar 29 19:32 .ssh/
drwxr-xr-x 1 Tom     0 Mar 29 13:49 .zbstudio/
drwxr-xr-x 1 Tom     0 Jun 16  2016 temp/
drwxr-xr-x 1 Tom     0 Jul 13  2016 vimfiles/
-rw-r--r-- 2 Tom   365 Mar 30 10:37 .aliases
-rw-r--r-- 1 Tom 16028 Mar 30 12:12 .bash_history
-rw-r--r-- 2 Tom  2807 Mar 30 12:12 .bash_profile
-rw-r--r-- 2 Tom  2177 Mar 29 23:24 .functions
-rw-r--r-- 1 Tom  1091 Mar 30 10:34 .gitconfig
-rw-r--r-- 1 Tom  8907 Mar 29 14:45 _viminfo
-rw-r--r-- 1 Tom  2444 Jul 13  2016 _vimrc
33819 bytes

Оскільки нова версія Git Bash для Windows підтримує --group-directories-first, нам більше не доведеться відступати sort. Незважаючи на те, що новий псевдонім не відображає стільки інформації, як попередній псевдонім, підвищення продуктивності більш ніж варте того. Як піклування, ви також отримуєте кольори!


Чудова відповідь! Але коли ти кажеш: "Після багатьох злому, я нарешті придумав однолінійний ..." Так, це насправді це не один "лайнер" у класичному розумінні. Це може мати сенс взяти цю логіку і зробити її окремим сценарієм оболонки і просто запустити її або назвати як псевдонім.
JakeGould

@JakeGould Ви швидкі! Я ще не закінчив прочитання своєї відповіді, і ви вже закінчили її читати і зняли коментар :). Так, це головний кандидат на функцію, але я був занадто лінивий у той час, тому просто кинув її у свій файл .bash_aliases. З іншого боку, я зазвичай записую функцію лише тоді, коли я не можу щось зробити без проходження параметрів.
thoan

@ 10basetom: Швидке запитання: Як отримати різні кольори для стовпців у ls? Я можу розфарбувати імена файлів за допомогою файлів за допомогою ls --color, але я не бачу способу отримати корисні кольори для стовпців. У чому секрет?
Піркс

@Pirx Я вважаю, що стовпці пофарбовані за замовчуванням підкреслення синтаксису Stack Exchange :-).
туан

Так, це, мабуть, так, але це чудова ідея, і рішення є ;-)
Pirx

6

У вас є кілька варіантів, залежно від того, чи хочете ви дотримуватися алфавітного порядку.

Ви можете просто спробувати:

ls -al | сортувати -k1 -r

або це, щоб зберігати алфавітний порядок для файлів з однаковими дозволами:

ls -al | сортувати -k1,1 -k9,9 -r

або, як сказало одинадцять81 (але ця версія перераховує все):

лс -ла | grep "^ d" && ls -la | grep "^ -" && ls -al | grep -v "^ [d | -]"


1
Це приємніше рішення ІМО. Використання декількох процесів і труб для сортування замість трубопроводів для сортування здається видом назад. Тим більше, що ls- al|sort -k1 -rпрацює. Чого не вистачало - це лише -rпрапор.
березень

@brice Річ , яка турбує мене про « свого роду» є те , що ./і ../не буде першим два рядки, в цьому порядку. Крім цього, я погоджуюся, що це більш ефективне рішення.
thoan

Як забарвити вихід?
Даніель

5

До відповіді delerious010 я додам, що якщо ви хочете замовити старий стиль:

LANG=C ls -la --group-directories-first

(або використовуйте LC_ALL або LANGUAGE або LC_COLLATE, встановлені на "C").

Це дасть щось подібне до:

.
..
DIR
Dir
dir
.hidden
123
UC_FILE
Uc_file
lc_file

Хоча, якщо я пригадую правильно, приховані точкові файли спочатку з’являлися перед каталогами.


2

Ось функція для цього (bash або zsh): І ... я не припускаю, що це найкращий спосіб, але це той, який я придумав і зараз використовую:

функція lss
{
    # Показує список каталогів із каталогіми вгорі.

    команда ls --color = завжди $ @ | egrep '^ d | всього'
    команда ls --color = завжди $ @ | egrep -v '^ d | всього';
}

Просто фій, здається, не працює. Щоб ls -lфільтрувати за таким типом файлів, потрібно використовувати формат довгого списку ( ). Також ця команда буде розбита на пробіли (в bash). Вам потрібно цитувати так: "$@"Якщо ви хочете скористатися таким підходом, ви можете зробити щось подібне:function lss {local temp="$(command ls -l --color=always "$@")"; egrep --color=never '^d|total' <<<"$temp"; egrep --color=never -v '^d|total' <<<"$temp"}
Шість

2

ls -laX покаже вам спочатку каталоги в алфавітному порядку, але накрутить список файлів.

Довгі варіанти:

ls
    -l    # List
    --all
    -X    # Sort alphabetically by entry extension

Це спрацює лише в тому випадку, якщо ви можете бути абсолютно впевнені, що кожен каталог не має крапок у своєму імені.
одинадцять81

1

Інший спосіб ...

find . -d 1 -type d | ls -la | sort -r 

АБО

ls -la | sort -r

АБО

d=`find . -type d -d 1`;f=`find . -type f -d 1`; echo -e -DIRS- "\n$d\n" -FILES- "\n$f"

Що вони роблять? Де ви навчились їх набирати?
Тамара Війсман

Добре, моя краща ОС - Debian Linux. Версія пакета lnu утиліти Debian для ls підтримує параметр --show-каталоги - перший варіант ... коли я почав використовувати OSX, просто схопив усі мої файли bash dot з мого вікна Debian і запустив їх у свій домашній каталог ... I У мене було багато bash_aliases, які так зламалися ... Саме тоді мені довелося розібратися у деяких робочих обставинах для моїх псевдонімів ...
Едді Б

Перший - трохи зайвий ... Дійсно немає причин сортувати каталоги, оскільки це порядок, який нам потрібно змінювати, а не каталоги ... 'ls -la | sort -r '- це те, що реально працює. В основному це твердження ... 1) А) Знайти. -d 1 -тип d (Почніть з цього каталогу, шукайте по одній глибині каталогу та шукайте лише каталоги) B) ls -la (список файлів усіх атрибутів) C) Сортування їх у зворотному порядку 2) Виконайте як 1) просто відкиньте знахідку. .. це не потрібно ... Мені дійсно подобається рішення Студерів краще ... :-)
Едді Б

1

TL; DR

alias ls='ls -lhF --color'

list_sorted() {
    ls $* | grep "^d";
    ls $* | grep "^-";
    ls $* | grep -v -E "^d|^-|^total"
}

alias ll=list_sorted

Пояснення

Я використовую комбінацію рішень, наданих у відповідях та коментарях тут.

За замовчуванням ls

Перш за все, я перезаписую поведінку за замовчуванням для ls:

  • -l: Список завжди відображається як одновимірний вертикальний список
  • -h: Відображення розмірів файлів, зрозумілих для людини (наприклад, 4,0 К замість 4096)
  • -F: Відображення індикаторів, як кінцева коса риса для каталогів
alias ls='ls -lhF --color'

Розширений ll

Далі я записую функцію, що містить логіку сортування. Для кожного lsя передаю будь-які спочатку передані йому аргументи. Це дозволяє мені використовувати псевдонім з іншого робочого каталогу, ніж той, який я хочу перелічити (тобто ls -a ~).

Крім того, кожен дзвінок до lsпередається в grepкоманду. Тут сортування відбувається. ls -l | grep "^d"наприклад лише переліки каталогів. Якщо каталоги повинні бути перераховані першими, це також має стати першим у функції. Наступне - файли.

Нарешті, я показую все, що не є ні каталогом, ні файлом (ні рядком із загальним розміром вмісту каталогів). Це робиться через стиснення directoy, регулярні записи файлів та загальний запис, а потім інвертування результату через -vаргумент.

list_sorted() {
    # List directories
    ls $* | grep "^d";
    # List regular files
    ls $* | grep "^-";
    # List everything else (e.g. symbolic links)
    ls $* | grep -v -E "^d|^-|^total"
}

Нарешті, я псевдонім функцію новій команді. Зокрема, я не хочу перезаписувати, lsякщо моя функція порушується в деяких сценаріях. Тоді я хочу вміти користуватися ls. Крім того, ви завжди можете викликати невідчужувану lsкоманду шляхом виклику \ls.

alias ll=list_sorted

Примітки

  • Я використовую ;замість цього &&як роздільник для команд. В іншому випадку не вдається перерахувати вміст каталогів, що не містять каталогів (перша команда ls оцінює значення false, таким чином не дозволяючи виконувати наступну команду, оскільки вона поєднана з &&. ;Уникає цього.)

0

Це сценарійне рішення. Перелічує лише імена, без даних про введення, за алфавітом, без регістру та відформатованими у стовпці. Хоча це рядок-головний замість основного стовпця, як вихідний показник ls. Стовпці трохи заплутані, якщо є ім'я файлу з> 26 символами.

rm -f /tmp/lsout
ls -1p | grep / | sort -f >> /tmp/lsout
ls -1p | grep -v / | sort -f >> /tmp/lsout

IFS=$'\n' read -d '' -r -a lines < /tmp/lsout

printf "%-24s  %-24s  %-24s\n" "${lines[@]}"

І ще, з деяким додатковим форматуванням.

rm -f /tmp/lsout
echo "  ---- Directories ---- " >> /tmp/lsout
ls -1p | grep / | sort -f >> /tmp/lsout
IFS=$'\n' read -d '' -r -a lines < /tmp/lsout
printf "%-24s  %-24s  %-24s\n" "${lines[@]}"

rm -f /tmp/lsout
echo "  ------- Files ------- " >> /tmp/lsout
ls -1p | grep -v / | sort -f >> /tmp/lsout
IFS=$'\n' read -d '' -r -a lines < /tmp/lsout
printf "%-24s  %-24s  %-24s\n" "${lines[@]}"

Вихід для останнього виглядає наступним чином мінус кольори:

  ---- Directories ----   archive/                  bookmarks/              
Desktop/                  Documents/                Downloads/              
fff/                      health/                   Library/                
Movies/                   Music/                    Pictures/               
Public/                   rrf/                      scifi/            
testdir/                  testdir2/                                         
  ------- Files -------   @todo                     comedy            
delme                     lll                       maxims                  
schedule                  vtokens style

Просто пам’ятайте, що не створювати псевдонім і не змінювати поведінку ls за замовчуванням, оскільки цей сценарій називає його

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.