Сортування у випадку нечутливості до випадків у Mac OSX


30

Як я можу зробити lsкоманду в Max OS X Lion сортування файлів і каталогів аналогічно тому, як робить Ubuntu Linux (нечутливі до регістру, каталоги НЕ зверху, крапки файлів НЕ зверху)? В ідеалі я хотів би зробити це без передачі даних на іншу команду, наприклад сортування.

Наприклад, я хочу побачити:

foo
Foobar
MyStuff/
.stuff/
test.txt

замість:

.stuff
Foobar
MyStuff/
foo
test.txt

У Linux, lsпорядок сортування контролюється, зокрема, локальною системою LC_COLLATE. Коли LC_COLLATE=en_US.UTF-8, я буду сортувати предмети, як я хочу. Коли LC_COLLATE=C, lsбуде сортувати схоже на OS X.

LC_COLLATEвстановлено en_US.UTF-8в OS X, але lsвсе ще сортує старий POSIXспосіб. Хтось знає, як я можу змусити це поводитись більше, як Linux?


Якщо це допомагає: apple.stackexchange.com/a/22304/8546 зауважує, що HFS Plus зазвичай налаштований на нечутливість до регістру, але зберігає регістр .
Грем Перрін

Відповіді:


16

Це може бути неможливо:

Переглядаючи вихідний код для ls , він використовує strcoll для сортування імен файлів, і тому слід поважати LC_COLLATE.

Деякі публікації в Інтернеті припускають, що локалі в BSD (і Darwin / OS X) дещо розбиті в порівнянні з тими в Linux. Я написав власну програму швидкого сортування, в якій явно встановив її локаль, і протестував її за допомогою локалів en_US.UTF-8 та C на моїй машині (Mac OS 10.6.3) та університетської машини (Linux, FC11?). У той час як сортування працює, як очікувалося, на машині Linux ("a B c" vs "B a c"), mac завжди сортує їх як "B a c".

Джерело: http://ask.metafilter.com/130292/CaseInsensitive-LS-on-Mac-OS-X

ОРИГІНАЛЬНИЙ ВІДПОВІДЬ

Ця команда не сортує файли з крапками, але показує додаткові списки каталогів

ls -f1 

Я наблизився до цього:

.
..
.stuff
foo
Foobar
MyStuff
test.txt

1
Цікаво, що "відключення сортування" з опцією -f насправді, здається, сортує її як очікувалося. Я припускаю, що це файлова система / HFS + сортування записів з більш "природним" зіставленням.
Геррі

6

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

ls -f1 -alF -G

У ньому перераховані всі деталі та їх сортування, ігноруючи регістр.


4

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

Якщо ви готові встановити MacPorts (або Homebrew, або Fink), версія ln GNU робить саме те, що ви хочете. Я сам використовую MacPorts, тому такий підхід я поясню:

  1. Завантажте та встановіть MacPorts:

    http://www.macports.org

  2. Встановіть пакет GNU Coreutils:

    sudo port install coreutils

  3. Тепер ви повинні мати GNU LS: gls. Спробуйте в каталозі, який містить елементи, які починаються з великих і малих літер:

    gls -U

    (Цей -Uпараметр насправді означає "несортований", але в OS X це бажаний ефект, що робить його нечутливим.)

  4. Додайте цей псевдонім у свій, .bash_profileщоб регулярний lsпрацюватиме так, як ви хочете (мені подобається вихід кольорів, але ви можете пропустити це, якщо хочете; вам потрібне лише -U):

    alias ls='gls -U --color'

Зауважте, що -Uопція, ймовірно, не працюватиме на інших платформах. В OS X завжди здається, що це робиться правильно (можливо, тому що HFS + є фактично нечутливим до обставин - технічно відомим), але якщо ви спробуєте це на вікні Linux, результати, швидше за все, просто не будуть сортували взагалі.


1
3. Мабуть, більше не має бажаного побічного ефекту (опція U) під macOS> = 10.13 завдяки новому APFS.
Маріус Хоферт

1
Так ... не схоже, що це можливо зробити за допомогою APFS.
Джейсон Сімс

Підтвердження працює, проте 10.12. Спасибі!
Полковник Паніка

4

Додавши до написаного вище Майка, я трохи пізніше взяв це і знайшов спосіб визначити власні правила зіставлення.

Визначення локалі знаходяться в / usr / share / locale /. Кожна папка є локальним і має файл (або посилання) LC_COLLATE, який визначає, які символи є "однаковими" (наприклад, що U, u та ü слід вважати однаковими при замовленні). Ви можете скопіювати каталог, і це створить нове визначення локалі:

$ sudo cp -R en_GB.UTF-8/ en_GB.UTF-8-CI/

Тепер у вас з’явиться новий локал, який називається 'en_GB.UTF-8-CI' ('CI' для нечутливого до регістру), і ви можете використовувати LC_COLLATE звідти.

Тепер, щоб змінити LC_COLLATE в новій мові, ви можете завантажити джерела локалі з http://www.opensource.apple.com/source/adv_cmds/adv_cmds-119/usr-share-locale.tproj/colldef/ , відредагуйте це це найближче до того, що ти хочеш, і біжи

$ colldef < <new collation file>
$ sudo cp LC_COLLATE /usr/share/locale/en_GB.UTF-8-CI/

і тепер, коли ти біжиш

$ LC_COLLATE=en_GB.UTF-8-CI ls

у вас буде сортування за вашими правилами.

Так, саме для цього потрібно зробити так, щоб «сортування» не залежало від регістру.


2

Як вирішення можна використовувати функцію та псевдонім:

function lssorted() { /bin/ls "$@" | sort -f ;}
alias ls='lssorted'

Це створює невідчутливо відсортований випадок для стандартної команди ls.


1
Маю зазначити: це не вдасться, якщо, наприклад, використовується -l. Тоді ls виробляє ще один рядок "total X" на початку, який також буде відсортовано.
Арн

2

Використання

ls -f

працює для мене.

-f офіційно вимикає будь-яке сортування, але, схоже, тоді просвічує оригінальний сорт HFS, що є саме нечутливим до випадку випадком.

Я думаю, це насправді залежить від того, чи є ваш формат HD у форматі чутливим до регістру чи ні, але оскільки формат HFS, нечутливий до регістру, є типовим для системних дисків Mac OS X, це має працювати для більшості користувачів.


Це, безумовно, правильна відповідь. Єдине питання з цим полягає в тому, що він неявно включається -a, і немає жодного способу вимкнути це, що покаже вам файли / папки, починаючи з періоду, в тому числі. і ...
лінзовет

1
Інша проблема (зараз) полягає в тому, що це, здається, більше не працює в macOS> = 10.13 завдяки новому APFS.
Маріус Гоферт

1

Натхненний відповіддю Майка, я додав наступне до / etc / bashrc, і це чудово працює у Mojave. Він містить список прихованих файлів у кінці, коли додається -a, але це мене не турбує.

export LC_COLLATE="cs_CZ.ISO8859-2"; alias ls='ls -lhFG'

Ви можете побачити нову конфігурацію, виконавши команду locale. Щоб повернутись, просто видаліть рядок з / etc / bashrc та увійдіть назад у термінал.

$ locale
LANG="en_US.UTF-8"
LC_COLLATE="cs_CZ.ISO8859-2"
LC_CTYPE="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_ALL=

Зауважте, що ні ls -f1, ні ls -f не працювали на мене в Мохаве. Я закінчив справді несортований список. Тільки рішення, яке я надав, працювало для мене в Мохаве.


Найкраща відповідь, але наведений приклад робить занадто багато. Його слід обрізати так: ввести наступний рядок у свій .bashrcабо .zshrc:alias ls="LC_COLLATE=cs_CZ.ISO8859-2 ls"
user1561489

0

Виконати:

$ type ls

Ви, ймовірно, виявите, що ваша lsкоманда є псевдонімом.


У Linux: ls is /bin/ls. На OS X: ls is hashed (/bin/ls). У будь-якому випадку, навіть якщо я телефоную /bin/lsбезпосередньо, він все ще не сортується відповідно до LC_COLLATE.

2
Це дивно, я б погодився, щоб ваша lsкоманда була включена --group-directories-first. Це все ще може бути зроблено деінде, тільки не псевдонім.
MikeyB

0

Якщо ви головним чином переймаєтесь порядком сортування точкових файлів, ви можете сортувати за розширенням : Використовуйте lsкоманду з GNU Fileutils з опцією --sort=extension. (Ви можете встановити GNU Fileutils, наприклад, через макпорти.)


0

ls сортує відповідно до LC_COLLATE, це просто те, що більшість всіх файлів LC_COLLATE налаштовані робити сортування залежно від регістру. http://collation-charts.org/fbsd54/

Існують два, які встановлені для сортування не залежно від регістру: cs_CZ.ISO8859-2 та et_EE.ISO8859-15 et_EE.ISO8859.15 не сортує "Z" так, як хотіли б мовці англійської мови. cs.CZ.ISO8859-15 добре працює з алфавітом, я просто хочу, щоб він сортував "~" перед буквеними символами.

Моє рішення: LC_COLLATE = cs_CZ.ISO8859-2 / bin / ls -FG

Цікаво, чи можна зробити власний файл LC_COLLATE для обробки "." так, як ти хочеш, і "~" так, як я хочу.

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