Як спочатку зробити сортування символів підкреслення?


20

Мені подобається можливість називати файли та каталоги з префіксом підкреслення, якщо це щось, що я хочу зберігати окремо від інших файлів і каталогів на одному рівні. Наприклад, у Windows та Mac, префіксація файла із підкресленням сортує його вгорі, перед файлами, що починаються з буквено-цифрового символу.

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

Виходячи з локальної локальної установки демонстраційного сайту ICU Collate для en_US_POSIX, очевидно, є такий порядок сортування, який я шукаю (ви повинні відредагувати зразкові дані та додати деякі підкреслення, щоб перевірити їх). Але я не розумію, як застосувати це до своєї оболонки Linux.

В ідеалі я хотів би мати можливість встановити щось у моєму конфігурації bash, щоб ls завжди впорядковував підкреслення. Як би я пішов робити це?


Я не можу відтворити за допомогою ICU Collate за замовчуванням або за допомогою en_US_POSIX.txt через "Вибрати правила для локалі". Чи можете ви пояснити використовувані налаштування?
Мікель

Подібне запитання askubuntu.com/questions/47702/…
Мікель

@Mikel, використовуючи посилання, яке я надав вище, додайте деякі підкреслення до тестових даних, а потім подайте, щоб побачити результати сортування.
Том Ожер

Саме це я і зробив, а рядки, що починаються з підкреслення, відсортуються посередині, а не на початку, як ніби підкреслення там не було.
Мікель

1
Відповідне питання, яке стосується фактичної зміни визначення порядку порівняння, - unix.stackexchange.com/questions/421908 .
JdeBP

Відповіді:


5

Якщо ви не можете lsвпорядкувати потрібний спосіб, спробуйте розширити оболонку.

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

ls -lf _* [!_]*

Припустимо, що у вас є файли

_a a _b b _c c

це як біг

ls -lf _a _b _c a b c

Пояснення:

_* - це шаблон оболонки, що відповідає будь-якому імені файлу, починаючи з підкреслення, розширеного в алфавітному порядку.

[!_]*відповідає будь-якому імені файлу, що не починається з підкреслення, розширеного в алфавітному порядку.

-fкаже , lsщоб НЕ сортувати, так як оболонка вже зробив.

Додаткова інформація: розширення назви файлу bash

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

ls -lfd _* [!_]*

7
До речі, DOS / Windows / OSX насправді не ставлять підкреслення перед чим-небудь іншим: вони сортують регістр без урахування підкреслення перед буквами, але деякі інші знаки пунктуації йдуть перед або після підкреслення. Використовувати _для того, щоб файли з’являлися спочатку - це хакерська система; і версія Unix цього хака полягає в тому, щоб запустити ім'я файлів з великої літери: за замовчуванням unix умовою є використання лише малих літер у назвах файлів.
Жил "ТАК - перестань бути злим"

4
Або нулі; напр 00README.
mattdm

1
@Gilles +1 - найкраща практика для використання Unix для використання важливих файлів, щоб зробити їх першими. Зрештою, якщо це умова, мабуть, найкраще, щоб я просто прийняв це, а не намагався змусити unix поводитись так, як це роблять інші ОС, я можу використовувати конвенції, розроблені для Mac чи Windows. Дякую за чудову пораду.
Том Ожер

1
@TomAuger -fкаже lsне робити власне сортування, тому він відображає свої аргументи у порядку їх передачі. Результат кожного оболонки підстановлювальний розширення _*і [!_]*є лексикографічно відсортованого списку.
Жил "ТАК - перестань бути злим"

1
@TomAuger Аргументи для lsсортування (у дві групи: ті, що починаються _, потім інші), коли вони генеруються оболонкою. Біжи, echo ls -lf _* [!_]*щоб побачити, що станеться. -fПрапор говорить lsне робити якусь - або сортування.
Жил "ТАК - перестань бути злим"

16

Якщо ви не хочете змішувати малі та великі регістри, встановіть свою локальну мову C, яка містить символи в їх числовому порядку. _потрапляє між великими та малими літерами.

$ LC_COLLATE=C ls    
BAR  FOO  _score  _under  hello  world
$ LC_COLLATE=en_US ls                    
BAR  FOO  hello  _score  _under  world

Налаштування LC_MESSAGESмови (мова повідомлень про помилки), LC_CTYPE(набори символів) та LC_TIME(формат дати та часу) дуже корисні. LC_COLLATEі, LC_NUMERICяк правило, більше проблем, ніж вони варті, я не рекомендую їх встановлювати. Правильне лексикографічне сортування складніше, ніж LC_COLLATEпередбачається, і воно може викликати всілякі дивні поведінки, коли ви використовуєте діапазони символів у регулярних виразах. LC_NUMERICздебільшого косметичний, за винятком випадків, коли щось страшенно не так, оскільки якась програма видала число з десятковим роздільником, ніж ..


+1 Дуже цікаво. Отже, використовуючи цю форму, ви тимчасово встановлюєте змінну середовища LC_COLLATE саме для цього одного екземпляра ls? Це так?
Том Ожер

1
Будь-яким способом зробити підкреслення перед тим, як великі літери?
Том Ожер

1
@TomAuger Так, VAR=value cmdнабори VARдля valueтільки в середовищі cmdі не зачіпає значення (або відсутність значення) в оболонці , де ви запустите його. Щоб підкреслення з’явилося перед великими літерами, вам потрібно визначити власні параметри локалі. Це можливо, але незручно використовувати, оскільки, принаймні, під Linux, стандартна бібліотека шукає лише визначення локалів у /usr/lib/locale- немає ~/.localeзмінної середовища або середовища, де ви могли б встановити свої en_tomналаштування.
Жил "ТАК - перестань бути злим"

@TomAuger Якщо мова йде лише про lsкоманду, перейдіть за пропозицією Мікеля .
Жил "ТАК - перестань бути злим"

2

На жаль, Linux використовує glibc для своєї локальної інформації, а не ICU, тому немає ніякого способу безпосередньо застосувати це до Linux, не витрачаючи багато зусиль або на переоснащення ICU в glibc, або на доповнення інформації про локал у glibc.


-4

Якщо додати -fперемикач (без сортування), це показало для мене саме так.

man ls

[root@dusknoir ~/java/test]# ls -fl
total 0
-rw-r--r--  1 root  wheel  0 Jun  1 13:27 _1
-rw-r--r--  1 root  wheel  0 Jun  1 13:27 _2
-rw-r--r--  1 root  wheel  0 Jun  1 13:27 _3
-rw-r--r--  1 root  wheel  0 Jun  1 13:27 1
-rw-r--r--  1 root  wheel  0 Jun  1 13:27 2
-rw-r--r--  1 root  wheel  0 Jun  1 13:27 3

6
Тільки тому, що так вони зберігаються у файловій системі.
Ігнасіо Васкес-Абрамс

3
Вибачте, але ця відповідь явно неправильна. Тест: touch 3 1 _1 _3 2 _2 && ls -flвиходи2 . 1 3 _2 _3 .. _1
Марко
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.