Команда sort
Вступ
Команда sort дуже давня, вона може бути зразком програмування утиліт у ранніх 70-х роках минулого століття. У команди безліч опцій та їх різноманітні поєднання, а також способи завдання роздільників добре розвивають пам'ять і уяву.
Програма sort без опцій
Якщо мені спаде на думку розсортувати боржників за алфавітом, то я дам команду:
А можу й у зворотному алфавіті порядку:
Опції -n та -k
Доводиться розглядати ці дві опції разом, оскільки вони дозволяють одразу ввести читача в курс справи, а не розглядати безліч простих прикладів.
Опція -n використовується завжди, коли потрібно сортувати числа, очевидно в порядку зростання (або зменшення, додавши опцію -r).
Опція -k дозволяє задавати об'єкт сортування: всі ці стовпці, колонки тощо елементи форматування файлу.
Отже, я хочу виявити найзлісніших боржників у міру спадання боргу:
Опція -n повідомляє команді, що доведеться сортувати числа, опція -r , що у зворотному порядку, а опція -k задає об'єкт - другу колонку тексту.
У нас є ще одна колонка з числами місяців, можна для тренування розсортувати список за числами різних місяців, хоча жодного практичного сенсу це не має:
Бачите, у п'ятій колонці числа йдуть по зростаючій. Давність програми дається взнаки ще й у тому, що можна вводити опції по-різному. Наприклад, можна набрати:
з тим самим результатом. І навіть:
Повинен попередити, що є два стилі завдання об'єкта сортування. (Майте на увазі, англійською ці об'єкти називаються fields, що наші перекладачі перекладають як поля; перекладають-то правильно, тільки українські поля у файлі знаходяться по краях тексту, і не мають жодногоставлення до справи. Якщо бачите в манах слова: fields або поля, знайте - йдеться про колонки, стовпці, або інші елементи форматування тексту). Але повернемося до стилів завдання цих самих "полів".
Новий стиль використовує опцію -k та цифри, що вказують порядковий номер потрібної колонки з початку рядка (починаючи з 1). Візьмемо файл pay.txt:
І дамо команду:
Сортування відбулося за першим символом другої колонки, що не дало нам жодної користі. Змінимо команду:
Вказавши п'ятий символ (вважаючи точки) у другій колонці (-k2.5), ми отримали алфавітний список співробітників.
Тепер розглянемо файл ivanov.txt:
Розсортуємо його строго по другій колонці, не зважаючи на колонку з ініціалами:
Для цього ми використали опцію -k 2,2. Перша двійка означає початок об'єкта сортування (колонки тексту), а друга двійка через кому - кінець об'єкта сортування. Тобто, команді заборонено використовувати для сортування символи після останньої літери другої колонки.
Ми, що Іванові йдуть у тому порядку, як у вихідному файлі. А якщо ми хочемо розсортувати Іванових за абеткою їх ініціалів?
Ми наказали використовувати для сортування другу та третю колонки тексту (-k 2,3). Тепер Іванові відсортовано і за ініціалами. Але важливіше знати, хто з Іванових більше повинен:
Тепер ініціали не сортуються, оскільки первинне сортування проводиться строго по другій колонці (-k 2,2), а вторинне сортування (-k 4n) по 4 колонці, в нумерологічному порядку, і лише серед Іванових (тобто тих, хто не відрізнявся) за результатами первинного сортування). Тепер стає зрозуміло, навіщо потрібне таке сортування – строго по заданому об'єкту.
Сподіваюся, що новий стиль написання опції -k став зрозумілим. Новий стиль застосовується навсіх сучасних версіях команди sort, включаючи GNU Coreutils, якими укомплектовані нові дистрибутиви Лінукс.
Коротко торкнуся старого стилю написання опції -k. Ось приклад завдання третього стовпця для нумерологічного сортування:
Новий стиль: sort -k 3,3n имя_файла
Старий стиль: sort +2 -3n имя_файла
Старий стиль працює на нових версіях програми, але розглядати його в подробицях я не стану, щоб не заплутатися самому і не заплутати читача. Нам вистачить плутанини та з новим стилем.
Ми вже познайомились із нею. Вона змушує команду sort сортувати у зворотному порядку. (Від 'z' до 'a' та від 1000000 до 0).
Я не можу не зупинитися на одній дивовижній здібності команди sort – вона може сортувати навіть місяці. Повернемося до файлу debts.txt:
Назви місяців у нас у 4 колонці, тому пишемо:
Вуаль! Мені це чомусь здається дивом. Можна задати ту саму команду і по-іншому:
Опція М перетворює перші три непробільні символи зазначеного стовпця в великі літери (Скажімо, SEP означає SEPtember), а потім порівнює їх і розташовує в порядку річного кола.
До цих пір ми розглядали файли, в яких роздільником колонок або стовпців був пробіл, що встановлено за замовчуванням. Щоб встановити інший роздільник, необхідно використовувати опцію -t.
Дозволяє вказати інший роздільник об'єктів сортування замість пробілу. Повернемося до файлу pay.txt:
Вперше, щоб розсортувати боржників на прізвища, ми вказували п'яту букву в третьому стовпці (вважаючи роздільником стовпців прогалини). Є інший спосіб вирішити це завдання:
Тепер ми задали роздільником крапку та вказали четверту колонку.
Давайте розсортуємо по алфавіту шелли, доступні в системі, вказавши роздільником слеш(-t '/'):
У директорії / etc маса файлів, в яких зустрічаються різні роздільники. Часто це двокрапка:
Сподіваюся, з роздільниками все ясно, правила їхнього завдання дуже нагадують команду cut.
Ця опція перевіряє порядок сортування сама нічого не сортуючи. Створимо файл 123.txt:
Висновок "неправильний порядок: 1" повідомляє номер рядка з першою помилкою.
Приховує однакові об'єкти. Якщо в процесі сортування виявилося кілька однакових об'єктів, то буде виведено лише перший із них, інші проігноровані:
Залишився лише один Іванов із трьох.
Якби ми задали команду трохи інакше:
то всі Іванові залишилися б на своїх місцях. Дайте відповідь: чому? (Відповідь у додатку [1]).
Ігнорує прогалини на початку рядків, і сортує так, наче прогалин немає. Візьмемо файл run.txt
Застосуємо команду sort без опцій:
Фактично відбулося сортування за кількістю прогалин, оскільки пробіл передує буквам у порядку сортування. Введемо команду:
Тепер рядки відсортовані за абеткою, незважаючи на прогалини.
Трохи ускладнимо файл run.txt
І спробуємо збудувати тварин за алфавітом:
Нічого не виходить – сортується кількість прогалин. Але варто додати опцію -b
як усе стає на свої місця.
Визнає лише літери, цифри та прогалини та сортує як у словнику.
Дуже схожа на попередню опцію -d, але не така "сувора". Вона визнає лише друковані символи, ігноруючи всі спеціальні.
При звичайному сортуванні, великі літери йдуть раніше малих:
А з опцією -f усі рівні:
Дозволяє сортувати числа, записані у загальній математичній формі. Візьмемо файл notation.txt:
і спробуємо розсортувати його звичайною опцією-n:
і зазнаємо невдачі. Тоді застосуємо опцію -g:
Тепер числа вишикувалися по ранжиру. Необхідно сказати, що використовувати опцію -g слід у крайніх випадках, коли не можна обійтися опцією -n. Справа в тому, що опція -g повільніша, і на великих файлах це стає помітним. Крім того, в Інтернеті з'являються повідомлення, що в деяких версіях GNU Coreutils sort помічено збої в роботі опції -g на великих файлах (більше 25Мб).
Дозволяє вказати директорію для тимчасових файлів, іншу, ніж за замовчуванням (/tmp або $TMPDIR).
При сортуванні великих файлів програма створює тимчасові файли і можна вказати, де їх розмістити. Приклад з очевидних причин дати не можу, просто пам'ятайте про цю опцію, якщо трапиться сортувати багатомегабайтні файли.
Також нагоді для сортування великих файлів. Вона створить в основній пам'яті буфер вказаного розміру.
До речі, коли мова зайшла про роботу з великими файлами, то корисно перемістити ці процеси на задній план, щоб можна було працювати, не чекаючи завершення процесу:
Ця опція скасовує пересортування. Що це таке? - Допустимо, ми сортували якийсь файл за певними, потрібними нам об'єктами сортування (полям, стовпцям, колонкам, символам усередині колонок і так далі), застосовували вторинне сортування (як у прикладі sort -k 2,2 -k 4n ivanov.txt), проте об'єкти, обрані нами, виявилися однаковими (рівними). У цьому випадку, за замовчуванням, команда sort проводить пересортування, вважаючи об'єктом сортування весь рядок загалом (як у разі сортування без опцій). Якщо ми хочемо зберегти початковий порядок рядків файлу, і не проводити фінальне пересортування, ми застосовуємо опцію -s.
Ця опція розглядає вихідний файл як набір рядків, розділених не знаком перенесеннярядки, а нульовим байтом. Навіщо це може знадобитися, я не знаю. Єдине, що мені вдалося знайти, це туманні вказівки, що ця опція може виявитися корисною у складі програмних каналів (pipes) з такими командами як 'perl -0', 'find -print0', і 'xargs -0' для сортування довільних файлових імен. Я поки що не розбирався з перерахованими програмами і не можу нічого сказати з цього приводу. Я також пробував підставляти опцію -z у численні приклади цієї статті, але ніякого сортування після додавання цієї опції не відбувалося.
Мабуть пережиток минулого, коли не було перенаправлення висновку. За допомогою цієї опції можна задати файл, куди буде розміщено виведення команди замість стандартного виведення на екран дисплея.
Післямова
Інша справа поєднання різних опцій один з одним. Якщо ви спорудили хитромудре заклинання з безлічі різних опцій, а воно не працює, спробуйте прибрати ту чи іншу опцію, може бути допоможе. А краще йти від простого до складного, поступово ускладнюючи команду, доки не досягнете потрібного результату. Добре допомагає набрати вашу команду в пошуковому рядку Гугла, раптом пощастить. До речі, тільки в цей спосіб я зміг розібратися з деякими опціями, про які пишу в цій статті.
Команда sort та кирилиця
Резюме команди sort
додаток
У першому випадку ми задали сортування строго по другій колонці (uk 2,2), тому програма бачила всіх Іванових однаковими, і включила опцію -u.
У другому випадку ми задали сортування, не вказавши кінець об'єкта сортування (uk2), і програма сортувала Іванових за наступними колонками (могла б до кінця рядка). І тут однакових об'єктів виявлено був, і опція -u не включилася.