<Предыдущая | Содержание: | Следующая>
sort
Ассоциация sort Программа сортирует содержимое стандартного ввода или одного или нескольких файлов, указанных в командной строке, и отправляет результаты на стандартный вывод. Используя ту же технику, которую мы использовали с кошка, мы можем продемонстрировать обработку стандартного ввода прямо с клавиатуры:
[я @ linuxbox ~] $ сортировать> foo.txt
cba
[я @ linuxbox ~] $ кот foo.txt
азбука
[я @ linuxbox ~] $ сортировать> foo.txt
cba
[я @ linuxbox ~] $ кот foo.txt
азбука
После ввода команды мы набираем буквы «c», «b» и «a», за которыми снова следует Ctrl-d для обозначения конца файла. Затем мы просматриваем полученный файл и видим, что строки теперь отображаются в отсортированном порядке.
С sort может принимать несколько файлов в командной строке в качестве аргументов, можно слияние несколько файлов в одно отсортированное целое. Например, если бы у нас было три текстовых файла и мы хотели бы объединить их в один отсортированный файл, мы могли бы сделать что-то вроде этого:
sort file1.txt file2.txt file3.txt> final_sorted_list.txt
sort file1.txt file2.txt file3.txt> final_sorted_list.txt
У sort есть несколько интересных опций. Вот неполный список:
Таблица 20-1: Общие параметры сортировки
Опция | Длинный вариант | Описание |
-b | --ignore-lead-blanks | По умолчанию сортировка выполняется по |
вся строка, начиная с | ||
первый символ в строке. Этот | ||
опция заставляет сортировку игнорировать | ||
ведущие пробелы в строках и | ||
вычисляет сортировку на основе первого | ||
непробельный символ в | ||
линии. | ||
-f | --игнорировать регистр | Делает сортировку нечувствительной к регистру. |
-n | --числовая сортировка | Выполняет сортировку на основе числовой оценки строки. Использование этой опции позволяет выполнять сортировку числовых значений, а не буквенных значений. |
-r | --задний ход | Сортировать в обратном порядке. Результаты в |
по убыванию, а не по возрастанию | ||
порядка. | ||
-k | --key =field1[,field2] | Сортировка по ключевому полю, расположенному |
от field1 в field2 а не | ||
вся линия. См. Обсуждение ниже. | ||
-m | - объединить | Считайте каждый аргумент именем |
предварительно отсортированного файла. Объединить несколько | ||
файлы в один отсортированный результат | ||
без выполнения каких-либо дополнительных | ||
сортировка. | ||
-o | --output =файл | Отправить отсортированный вывод в файл скорее |
чем стандартный вывод. | ||
-t | --field-separator =колесница | Определите разделитель полей |
персонаж. По умолчанию поля | ||
разделенные пробелами или табуляциями. |
Хотя большинство вышеперечисленных опций говорят сами за себя, некоторые из них - нет. Во-первых, давайте посмотрим на -n опция, используемая для числовой сортировки. С помощью этой опции можно сортировать значения на основе числовых значений. Мы можем продемонстрировать это, отсортировав результаты du команда для определения крупнейших пользователей дискового пространства. Обычно du Команда выводит результаты сводки в порядке именования путей:
[я @ linuxbox ~] $ du -s / usr / share / * | голова
252 / usr / share / aclocal
96 / usr / share / acpi-поддержка
8 / usr / share / adduser
196 / usr / share / alacarte
344 / usr / share / alsa
8 / usr / share / alsa-base 12488 / usr / share / anthy
8 / usr / share / apmd
21440 / usr / share / установка приложения
48 / usr / share / приложение-реестр
[я @ linuxbox ~] $ du -s / usr / share / * | голова
252 / usr / share / aclocal
96 / usr / share / acpi-поддержка
8 / usr / share / adduser
196 / usr / share / alacarte
344 / usr / share / alsa
8 / usr / share / alsa-base 12488 / usr / share / anthy
8 / usr / share / apmd
21440 / usr / share / установка приложения
48 / usr / share / приложение-реестр
В этом примере мы передаем результаты в чтобы ограничить результаты первыми десятью строками. Мы можем составить отсортированный по цифрам список, чтобы показать десять крупнейших потребителей космоса следующим образом:
[я @ linuxbox ~] $ du -s / usr / share / * | sort -nr | голова
509940 / usr / share / locale-langpack
242660 / usr / share / doc
197560 / usr / share / шрифты
179144 / usr / share / gnome
146764 / usr / share / myspell
144304 / usr / share / gimp
135880 / usr / share / dict
76508 / usr / share / значки
68072 / usr / share / apps
62844 / usr / share / foomatic
[я @ linuxbox ~] $ du -s / usr / share / * | sort -nr | голова
509940 / usr / share / locale-langpack
242660 / usr / share / doc
197560 / usr / share / шрифты
179144 / usr / share / gnome
146764 / usr / share / myspell
144304 / usr / share / gimp
135880 / usr / share / dict
76508 / usr / share / значки
68072 / usr / share / apps
62844 / usr / share / foomatic
С помощью -номер options, мы производим обратную числовую сортировку, при этом наибольшие значения отображаются первыми в результатах. Эта сортировка работает, потому что числовые значения находятся в начале каждой строки. Но что, если мы хотим отсортировать список на основе некоторого значения, найденного в строке? Например, результаты ls -l:
[я @ linuxbox ~] $ ls -l / usr / bin | голова
Всего 152948
-rwxr-xr-x | 1 | корень | корень | 34824 | 2016-04-04 | 02:42 | [ |
-rwxr-xr-x | 1 | корень | корень | 101556 | 2007-11-27 | 06:08 | A2P |
-rwxr-xr-x | 1 | корень | корень | 13036 | 2016-02-27 | 08:22 | соединение |
-rwxr-xr-x | 1 | корень | корень | 10552 | 2007-08-15 | 10:34 | ACPI |
-rwxr-xr-x | 1 | корень | корень | 3800 | 2016-04-14 | 03:51 | acpi_fakekey |
-rwxr-xr-x | 1 | корень | корень | 7536 | 2016-04-19 | 00:19 | acpi_listen |
-rwxr-xr-x | 1 | корень | корень | 3576 | 2016-04-29 | 07:57 | добавить часть |
-rwxr-xr-x | 1 | корень | корень | 20808 | 2016-01-03 | 18:02 | адрес2линия |
-rwxr-xr-x | 1 | корень | корень | 489704 | 2016-10-09 | 17:02 | adept_batch |
Игнорируя пока что ls можно отсортировать результаты по размеру, мы могли бы использовать sort чтобы отсортировать этот список также по размеру файла:
[я @ linuxbox ~] $ ls -l / usr / bin | sort -nr -k 5 | голова
-rwxr-xr-x | 1 | корень | корень | 8234216 | 2016-04-07 | 17:42 | Inkscape |
-rwxr-xr-x | 1 | корень | корень | 8222692 | 2016-04-07 | 17:42 | Inkview |
-rwxr-xr-x | 1 | корень | корень | 3746508 | 2016-03-07 | 23:45 | канитель-2.4 |
-rwxr-xr-x | 1 | корень | корень | 3654020 | 2016-08-26 | 16:16 | кванты |
-rwxr-xr-x | 1 | корень | корень | 2928760 | 2016-09-10 | 14:31 | gdbtui |
-rwxr-xr-x | 1 | корень | корень | 2928756 | 2016-09-10 | 14:31 | GDB |
-rwxr-xr-x | 1 | корень | корень | 2602236 | 2016-10-10 | 12:56 | сеть |
-rwxr-xr-x | 1 | корень | корень | 2304684 | 2016-10-10 | 12:56 | rpclient |
-rwxr-xr-x | 1 | корень | корень | 2241832 | 2016-04-04 | 05:56 | способность |
-rwxr-xr-x | 1 | корень | корень | 2202476 | 2016-10-10 | 12:56 | smbcacls |
Многие виды использования sort вовлекать обработку табличные данные, например, результаты ls команда выше. Если мы применим терминологию базы данных к приведенной выше таблице, мы бы сказали, что каждая строка является запись и что каждая запись состоит из нескольких поля, например, атрибуты файла, количество ссылок, имя файла, размер файла и так далее. sort умеет обрабатывать отдельные поля. В терминах базы данных мы можем указать один или несколько ключевые поля использовать как сортировать ключи. В приведенном выше примере мы указываем n и r параметры для выполнения обратной числовой сортировки и указать -к 5 , чтобы sort используйте пятое поле как ключ для сортировки.
Ассоциация k вариант очень интересный и имеет много функций, но сначала нам нужно поговорить о том, как sort определяет поля. Рассмотрим очень простой текстовый файл, состоящий из одной строки, содержащей имя автора:
Уильям Шоттс
Уильям Шоттс
По умолчанию sort видит в этой строке два поля. Первое поле содержит символы:
«Уильям»
а второе поле содержит символы:
«Выстрелы»
Это означает, что символы пробела (пробелы и табуляции) используются в качестве разделителей между полями и что разделители включаются в поле при выполнении сортировки.
Снова посмотрев на строчку из нашего ls На выходе мы видим, что строка содержит восемь полей, а пятое поле - это размер файла:
-rwxr-xr-x 1 root root 8234216 2016 04:07 inkscape
-rwxr-xr-x 1 root root 8234216 2016 04:07 inkscape
Для нашей следующей серии экспериментов давайте рассмотрим следующий файл, содержащий историю трех популярных дистрибутивов Linux, выпущенных с 2006 по 2008 год. Каждая строка в файле имеет три поля: имя дистрибутива, номер версии и дату выпуска в MM / DD. Формат / ГГГГ:
SUSE | 10.2 | 12/07/2006 |
Fedora | 10 | 11/25/2008 |
SUSE | 11.0 | 06/19/2008 |
Ubuntu | 8.04 | 04/24/2008 |
Fedora | 8 | 11/08/2007 |
SUSE | 10.3 | 10/04/2007 |
Ubuntu | 6.10 | 10/26/2006 |
Fedora | 7 | 05/31/2007 |
Ubuntu | 7.10 | 10/18/2007 |
Ubuntu | 7.04 | 04/19/2007 |
SUSE | 10.1 | 05/11/2006 |
Fedora | 6 | 10/24/2006 |
Fedora | 9 | 05/13/2008 |
Ubuntu | 6.06 | 06/01/2006 |
Ubuntu | 8.10 | 10/30/2008 |
Fedora | 5 | 03/20/2006 |
Используя текстовый редактор (возможно, напор), введем эти данные и назовем получившийся файл дистрибутивы.txt.
Далее мы попробуем отсортировать файл и посмотреть на результат:
[я @ linuxbox | ~] $ | отсортировать distros.txt |
Fedora 10 | 11/25/2008 | |
Fedora 5 | 03/20/2006 | |
Fedora 6 | 10/24/2006 | |
Fedora 7 | 05/31/2007 | |
Fedora 8 | 11/08/2007 | |
Fedora 9 | 05/13/2008 | |
СУЗЕ 10.1 | 05/11/2006 | |
СУЗЕ 10.2 | 12/07/2006 | |
СУЗЕ 10.3 | 10/04/2007 | |
СУЗЕ 11.0 | 06/19/2008 | |
Ubuntu 6.06 | 06/01/2006 | |
Ubuntu 6.10 | 10/26/2006 | |
Ubuntu 7.04 | 04/19/2007 | |
Ubuntu 7.10 | 10/18/2007 | |
Ubuntu 8.04 | 04/24/2008 | |
Ubuntu 8.10 | 10/30/2008 |
Ну, в основном это сработало. Проблема возникает при сортировке номеров версий Fedora. Поскольку «1» стоит перед «5» в наборе символов, версия «10» оказывается вверху, а версия «9» - внизу.
Чтобы решить эту проблему, нам нужно будет выполнить сортировку по нескольким ключам. Мы хотим выполнить алфавитную сортировку в первом поле, а затем числовую сортировку во втором поле. sort позволяет
несколько экземпляров -k вариант, чтобы можно было указать несколько ключей сортировки. Фактически, ключ может включать в себя ряд полей. Если диапазон не указан (как это было в наших предыдущих примерах), sort использует ключ, который начинается с указанного поля и продолжается до конца строки. Вот синтаксис нашей сортировки по нескольким клавишам:
[я @ linuxbox | ~] $ | sort --key = 1,1 --key = 2n distros.txt |
Fedora 5 | 03/20/2006 | |
Fedora 6 | 10/24/2006 | |
Fedora 7 | 05/31/2007 | |
Fedora 8 | 11/08/2007 | |
Fedora 9 | 05/13/2008 | |
Fedora 10 | 11/25/2008 | |
СУЗЕ 10.1 | 05/11/2006 | |
СУЗЕ 10.2 | 12/07/2006 | |
СУЗЕ 10.3 | 10/04/2007 | |
СУЗЕ 11.0 | 06/19/2008 | |
Ubuntu 6.06 | 06/01/2006 | |
Ubuntu 6.10 | 10/26/2006 | |
Ubuntu 7.04 | 04/19/2007 | |
Ubuntu 7.10 | 10/18/2007 | |
Ubuntu 8.04 | 04/24/2008 | |
Ubuntu 8.10 | 10/30/2008 |
Хотя мы использовали длинную форму параметра для ясности, -к 1,1 -к 2н будет точно эквивалентным. В первом экземпляре ключевого параметра мы указали диапазон полей для включения в первый ключ. Поскольку мы хотели ограничить сортировку только первым полем, мы указали 1,1 что означает «начать с первого поля и закончить с первого поля». Во втором случае мы указали 2n, что означает, что поле 2 является ключом сортировки и что сортировка должна быть числовой. Буква варианта может быть включена в конце спецификатора ключа, чтобы указать тип выполняемой сортировки. Эти буквы опций совпадают с глобальными опциями для sort программа: b (игнорировать начальные пробелы), n (числовая сортировка), r (обратная сортировка) и т. д.
Третье поле в нашем списке содержит дату в неудобном для сортировки формате. На компьютерах даты обычно имеют формат ГГГГ-ММ-ДД, чтобы упростить хронологическую сортировку, но наши даты имеют американский формат ММ / ДД / ГГГГ. Как отсортировать этот список в хронологическом порядке?
К счастью, sort обеспечивает путь. Ключевой параметр позволяет указать смещения внутри полей, поэтому мы можем определять ключи внутри полей:
[я @ linuxbox ~] $ сортировать -k 3.7nbr -k 3.1nbr -k 3.4nbr distros.txt
Fedora 10 11 ноября 25 г.
Ubuntu 8.10 10 октября 30 г.
[я @ linuxbox ~] $ сортировать -k 3.7nbr -k 3.1nbr -k 3.4nbr distros.txt
Fedora 10 11 ноября 25 г.
Ubuntu 8.10 10 октября 30 г.
SUSE | 11.0 | 06/19/2008 |
Fedora | 9 | 05/13/2008 |
Ubuntu | 8.04 | 04/24/2008 |
Fedora | 8 | 11/08/2007 |
Ubuntu | 7.10 | 10/18/2007 |
SUSE | 10.3 | 10/04/2007 |
Fedora | 7 | 05/31/2007 |
Ubuntu | 7.04 | 04/19/2007 |
SUSE | 10.2 | 12/07/2006 |
Ubuntu | 6.10 | 10/26/2006 |
Fedora | 6 | 10/24/2006 |
Ubuntu | 6.06 | 06/01/2006 |
SUSE | 10.1 | 05/11/2006 |
Fedora | 5 | 03/20/2006 |
Указав -к 3.7 мы инструктируем sort использовать ключ сортировки, который начинается с седьмого символа в третьем поле, что соответствует началу года. Аналогичным образом мы указываем -к 3.1 и -к 3.4 для выделения частей дня и месяца в дате. Мы также добавляем n и r параметры для достижения обратной числовой сортировки. В b включена опция для подавления начальных пробелов (номера которых меняются от строки к строке, что влияет на результат сортировки) в поле даты.
В некоторых файлах в качестве разделителей полей не используются табуляции и пробелы; например, / И т.д. / пароль
файл:
[я @ linuxbox ~] $ глава / etc / passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh lp:x:7:7:lp:/var/spool/lpd:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh
[я @ linuxbox ~] $ глава / etc / passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh lp:x:7:7:lp:/var/spool/lpd:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh
Поля в этом файле разделены двоеточиями (:), так как же нам отсортировать этот файл с помощью ключевого поля? sort обеспечивает -t возможность определить символ-разделитель полей. Чтобы отсортировать ПАРОЛЬ файл в седьмом поле (оболочка учетной записи по умолчанию), мы могли бы сделать это:
[я @ linuxbox ~] $ sort -t ':' -k 7 / etc / passwd | голова
я: x: 1001: 1001: Я ,,,: / домой / я: / bin / bash
[я @ linuxbox ~] $ sort -t ':' -k 7 / etc / passwd | голова
я: x: 1001: 1001: Я ,,,: / домой / я: / bin / bash
корень: x: 0: 0: корень: / корень: / bin / bash dhcp: x: 101: 102 :: / несуществующий: / bin / false
gdm: x: 106: 114: Диспетчер отображения Gnome: / var / lib / gdm: / bin / false hplip: x: 104: 7: системный пользователь HPLIP ,,,: / var / run / hplip: / bin / false klog : x: 103: 104 :: / home / klog: / bin / false messagebus: x: 108: 119 :: / var / run / dbus: / bin / false polkituser: x: 110: 122: PolicyKit ,,,: / var / run / PolicyKit: / bin / false pulse: x: 107: 116: демон PulseAudio ,,,: / var / run / pulse: / bin / false
корень: x: 0: 0: корень: / корень: / bin / bash dhcp: x: 101: 102 :: / несуществующий: / bin / false
gdm: x: 106: 114: Диспетчер отображения Gnome: / var / lib / gdm: / bin / false hplip: x: 104: 7: системный пользователь HPLIP ,,,: / var / run / hplip: / bin / false klog : x: 103: 104 :: / home / klog: / bin / false messagebus: x: 108: 119 :: / var / run / dbus: / bin / false polkituser: x: 110: 122: PolicyKit ,,,: / var / run / PolicyKit: / bin / false pulse: x: 107: 116: демон PulseAudio ,,,: / var / run / pulse: / bin / false
Указав символ двоеточия в качестве разделителя полей, мы можем выполнить сортировку по седьмому полю.