Дополнительные инструменты работы с текстом
Оглавление страницы:
Сортировка файлов с помощью команды SORT
Проверка факта сортировки файла
Сортировка с отбрасыванием повторяющихся строк
Задание ключа сортировки с помощью опции -k
Указание позиции, с которой начинается сортировка
Обработка результатов сортировки с помощью команд head и tail
Обработка результатов сортировки с помощью команд fold и cat
Передача результатов сортировки утилите awk
Объединение двух отсортированных файлов
Дополнительные примеры команды sort
Удаление повторяющихся строк с помощью команды UNIQ
Определение количества повторений
Отображение только повторяющихся строк
Проверка уникальности отдельных полей
Объединение файлов с помощью команды JOIN
Включение не совпадающих строк
Вырезание текста с помощью команды CUT
Вставка текста с помощью команды PASTE
Определение порядка вставки столбцов
Чтение данных из стандартного входного потока
Разделение файла на части с помощью команды SPLIT
Форматирование текста по ширине
Различные способы указания управляющих символов в утилите tr:
Сохранение выходного результата
Некоторые примеры использования:
Устранение повторяющихся символов
Преобразование прописных букв в строчные
Преобразование управляющих символов
Сравнение с несколькими символами
Преобразование строчных букв в прописные
Удаление определенных символов
Несколько правил работы с xargs
Применение к результатам команды find
Передача списка с разделяющими пробелами
Изменение прав для папок и файлов
Сортировка файлов с помощью команды SORT
sort - UNIX‐утилита, выводящая сортированное слияние указанных файлов на стандартный вывод с использованием установленной в среде локали, команда sort позволяет выполнять сортировку входного потока по различным полям (ключам сортировки), команда sort сортирует содержимое файла в алфавитном или нумерологическом порядке, если задать несколько файлов, то команда sort соединит их и, рассортировав, выдаст единым выводом. Это довольно мощная команда, которая весьма полезна при обработке журнальных файлов или реорганизации текстовых столбцов в файлах. В то же время следует быть внимательным при использовании ее многочисленных опций, так как зачастую можно получить неожиданные результаты. Не всегда понятна связь между указанной опцией и результатами, возвращаемыми командой sort. Некоторые опции перекрывают друг друга и, таким образом, допускают неоднозначную трактовку. Команда sort весьма древняя, она может служить образцом программирования утилит в ранних 70-х годах прошлого века.
http://citforum.ru/operating_systems/manpages/SORT
http://www.commandlinefu.com/using/SORT <<--------------
Опции команды sort
Команда sort имеет следующий формат: sort [опции] [входные_файлы]
Основные опции команды sort:
Команда выполняет конкатенацию(concatenatio «присоединение, сцепление»— операция склеивания объектов линейной структуры, отсюда название утилиты cat) указанных входных файлов, сортирует полученный текст и записывает результат в стандартный выходной поток. Если файлы не указаны, ожидается ввод данных с клавиатуры.
Позиция задается следующим образом: f[.c], где f - номер поля, c - позиция первого символа от начала поля. Если параматр с не указан, первым символом ключа считается первый символ поля.
Сохранение результатов сортировки
Чтобы сохранить результаты сортировки, укажите опцию -o и выходной файл. Можно также воспользоваться стандартным методом переадресации с помощью оператора >.
В следующем примере результаты сортировки сохраняются в файле results.out: $ sort video.txt > results.out
Тестовый файл
Для демонстрации возможного практического использования команды sort создадим файл video.txt, хранящий информацию из базы данных фирмы, которая занимается прокатом видеокассет. В перечень вошли видеокассеты, которые предлагались на протяжении последнего квартала. Поля файла имеют следующее назначение:
Название фильма.
Код фирмы–дистрибьютора.
Количество заказов за последний квартал.
Количество заказов за последний год.
По умолчанию, команда sort предполагает, что разделителем полей служит один или несколько пробелов. Если же поля разделены иначе, следует применять опцию -t. В нашем файле разделителем является двоеточие. Поэтому в тех примерах, где это необходимо, задается опция -t:.
$ ~ cat > video.txt
Boys in Company C:HK:192:2192
Alien:HK:119:1982
The Hill:KL:63:2972
Aliens:HK:532:4892
Star Wars:HK:301:4102
A Few Good Men:KL:445:5851
Toy Story:HK:239:3972
^C
$ ~
Индексация полей
При работе с командой sort не следует забывать, что команда обращается к первому полю как к полю 0, следующее поле имеет номер 1 и т. д. Если номера полей не указаны, вся строка считается единым полем. Обратимся к тестовому файлу и уточним, каким образом команда sort разбивает файл на поля:
Проверка факта сортировки файла
Каким образом можно узнать, отсортирован ли данный файл? Если он содержит, например, около 30 строк, то достаточно его просмотреть. А если в нем 400 строк? Примените команду sort -c, которая сама определит, отсортирован ли файл:
$ ~ sort -c video.txt
sort: video.txt:2: disorder: Alien:HK:119:1982
$ ~ sort video.txt | sort -c
$ ~
Впервой части примера команда sort считает, что файл не отсортирован. Во второй части, после сортировки сообщение не появилось, таким образом, файл является отсортированным.
Простейшая сортировка
В простейшем случае, чтобы отсортировать файл, достаточно передать его имя команде sort. Сортировка будет выполнена по строкам в алфавитном порядке:
$ ~ sort video.txt
A Few Good Men:KL:445:5851
Alien:HK:119:1982
Aliens:НК:532:4892
Boys in Company C:HK:192:2192
Star Wars:HK:301:4102
The Hill:KL:63:2972
Toy Story:HK:239:3972
$ ~
Сортировка в обратном порядке
Если необходимо отсортировать строки не по возрастанию, а по убыванию, задайте опцию -r:
$ ~ sort -r video.txt
Toy Story:HK:239:3972
The Hill:KL:63:2972
Star Wars:HK:301:4102
Boys in Company C:HK:192:2192
Alien:HK:119:1982
Aliens:НК:532:4892
A Few Good Men:KL:445:5851
$ ~
Сортировка с отбрасыванием повторяющихся строк
Иногда приходится иметь дело с файлом, содержащим повторяющиеся строки. Чтобы избавиться от них, достаточно воспользоваться командой sort с опцией -u. Ниже показан вариант тестового файла, в котором запись о фильме "Alien" ("Чужой", 1977 г.) повторяется дважды и, что получается в результате сортировки:
$ ~ cat > video_1.txt
Boys in Company С:HK:192:2192
Alien:HK:119:1982
The Hill:KL:63:2972
Aliens:HK:532:4892
Star Wars:HK:301:4102
A Few Good Men:KL.445:5851
Toy Story:HK:239:3972
Alien:HK:119:1982
^C
$ ~ sort -u video_1.txt
A Few Good Men:KL.445:5851
Alien:HK:119:1982
Aliens:HK:532:4892
Boys in Company С:HK:192:2192
Star Wars:HK:301:4102
The Hill:KL:63:2972
Toy Story:HK:239:3972
$ ~
Сортировка по заданному полю
В следующем примере файл сортируется по кодам фирм–дистрибьюторов. Поскольку требуемая информация находится во втором поле (ключ сортировки 1(, следует указать опцию +1. Кроме того, необходимо задать разделитель полей с помощью опции -t:, чтобы команда sort знала, как найти второе поле.
$ sort -t: +1 video.txt
Alien:HK:119:1982
Boys in Company С:HK:192:2192
Toy Story:HK:239:3972
Star Wars:HK:301;4102
Aliens:HK:532:4892
A Few Good Men:KL:445:5851
The Hill; KL:63:2972
Обратите внимание на то, что третье и четвертое поля также были отсортированы. Такова стандартная процедура: все последующие поля по умолчанию считаются ключами сортировки, расположенными в порядке убывания приоритета. Причем если вы посмотрите на конечные две строки, то заметите, что к этим полям применялась не числовая, а текстовая сортировка, учитывающая расположение символов в таблице ASCII–кодов. Поэтому поле со значением 445 оказалось расположенным раньше поля со значением 63.
Сортировка по числовому полю
Чтобы корректно отсортировать файл по четвертому, числовому, полю, укажите не только ключ сортировки (+3), но и опцию -n, включающую режим числовой сортировки. Следующая команда сортирует список фильмов по объемам проката видеокассет за год:
$ ~ sort -t: +3n video.txt
Alien:HK:119:1982
Boys in Company C:HK:192:2192
The Hill:KL:63:2972
Toy Story:HK:239:3972
Star Wars:HK:301:4102
Aliens:HK:532:4892
A Few Good Men:KL:445:5851
$ ~
Таким образом, выясняется, что фильм "A Few Good Men" является лидером видеопроката в текущем году.
Примечание:
Несмотря на наличие опции -n, данный пример работает правильно только потому, что четвертое поле является последним в строке. Причина этого объясняется ниже.
Задание ключа сортировки с помощью опции -k
Команда sort позволяет задать ключ сортировки немного по–другому. Если воспользоваться опцией -к, то поля (ключи сортировки) можно будет нумеровать, начиная с единицы, а не с нуля, что, в принципе, удобнее. Таким образом, чтобы выполнить сортировку по полю 4, достаточно задать опцию -k4n. Это позволит упорядочить список фильмов по объемам видеопроката за год.
$ ~ sort -t: -k4n video.txt
Alies:HK:119:1982
Boys in Company C:HK:192:2192
The Hill:KL:63:2972
Toy Story:HK:239:3972
Star Wars:HK:301:4102
Aliens:НК:532:4892
A Few Good Men:KL:445:5851
$ ~
Несколько ключей сортировки
При использовании опций [+позиция] и [-k] следует быть особенно аккуратным. Если внимательно прочитать их описание в таблице опций команды sort то можно были отметить такой факт: когда не указана конечная позиция, ключ сортировки считается заканчивающимся в конце строки. Подобная тонкость обычно вводит в замешательство новичков, которые пытаются выполнять числовую сортировку или сортировку с несколькими ключами. Если, к примеру, вы ссылаетесь на числовое поле только по номеру, а это поле не является последним в строке, причем за ним идут текстовые поля, данное поле также будет проинтерпретировано как текстовое, вследствие чего будут получены неправильные результаты.
Схожая проблема возникает при работе с несколькими ключами сортировки. Рассмотрим такой пример. Предположим, требуется отсортировать список фильмов по кодам дистрибьюторов (второе поле), а затем по названиям фильмов (первое поле). Если сослаться на поля по номерам, получим следующее:
$ ~ sort -t: -k2 -k1 video.txt
Alien:HK:119:1982
Boys in Company C:HK:192:2192
Toy Story:HK:239:3972
Star Wars:HK:301:4102
Aliens:HK:532:4892
A Few Good Men:KL:445:5851
The Hill:KL:63:2972
$ ~
Здесь ссылка на первое поле в действительности означает ссылку на всю строку, т. е. ключ с меньшим приоритетом включает в себя ключ с большим приоритетом, поэтому команда sort ведет себя не так, как можно было бы предположить на первый взгляд. Чтобы исправить ситуацию, необходимо четко указать длину каждого из ключей:
$ ~ sort -t: -k2,2 -k1,1 video.txt
Alien:HK:119:1982
Aliens:HK:532:4892
Boys in Company C:HK:192:2192
Star Wars:HK:301:4102
Toy Story:HK:239:3972
A Few Good Men:KL:445:5851
The Hill:KL:63:2972
$ ~
Опция -k2,2 ограничивает ключ сортировки вторым полем, а опция -k1,1 — первым.
Указание позиции, с которой начинается сортировка
Иногда в качестве ключа сортировки требуется задать не целое поле, а какую‑то его часть. В этом случае после номера поля необходимо через точку указать позицию символа, являющегося первым в ключе. Обратимся к примеру. Допустим, в нашем тестовом файле к каждому коду фирмы–дистрибьютора добавлен код региона дистрибуции:
$ ~ cat > video_2.txt
Boys in Company C:HK48:192:2192
Alien:HK57:119:1982
The Hill:KL23:63:2972
Aliens:HK11:532:4892
Star Wars:HK38:301:4102
A Few Good Men:KL87:445:5851
Toy Story:HK65:239:3972
^C
$ ~
Теперь мы хотим отсортировать файл по кодам регионов. Вот как можно это сделать:
$ ~ sort -t: -k2.3,2.4n video_2.txt
Aliens:HK11:532:4892
The Hill:KL23:63:2972
Star Wars:HK38:301:4102
Boys in Company C:HK48:192:2192
Alien:HK57:119:1982
Toy Story:HK65:239:3972
A Few Good Men:KL87:445:5851
$ ~
Данная команда означает, что ключом сортировки являются третий и четвертый символы второго поля.
Обработка результатов сортировки с помощью команд head и tail
При работе с большими файлами не обязательно выводить на экран весь файл, если требуется просмотреть только его начало и конец. Существуют удобные команды head и tail, упрощающие подобную задачу. Команда head отбирает первые п строк файла (по умолчанию 10), а команда tail — последние я строк (по умолчанию тоже 10).
Предположим, требуется быстро узнать, какой фильм пользуется наименьшим спросом в прокате. Для этого отсортируем файл по четвертому полю и направим результат команде head, задав в ней отображение одной строки:
$ ~ sort -t: -k4 video.txt | head -1
Alien:HK:119:1982
$ ~
Аналогичным образом можно выяснить, какой фильм чаще всего заказывали в этом году. Формат команды sort останется таким же, но результат будет передан команде tail:
$ ~ sort -t: -k4 video.txt | tail -1
A Few Good Men:KL:445:5851
$ ~
Обработка результатов сортировки с помощью команд fold и cat
Команда (fold - складывать), помещает перевод строки через каждые X символов до начала новой строки, как результат команда fold, разбивает длинные строки на строки требуемой длины, в сочетании с командой cat c опцией -n строки можно пронумеровать, Опции fold:
-b Учитывать символы возврата каретки
-s Разбивка по ближайшему пробелу
-w ширина Установить ширину выходной строки (по умолчанию — 80)
С использованием аргумента -w, команда fold позволяет установить максимальную длину строки.
$ sort -t: -k4 video.txt | cat -n | fold -w125
1 Alien:HK:119:1982
2 Boys in Company C:HK:192:2192
3 The Hill:KL:63:2972
4 Toy Story:HK:239:3972
5 Star Wars:HK:301:4102
6 Aliens:HK:532:4892
7 A Few Good Men:KL:445:5851
$
Передача результатов сортировки утилите awk
Может возникнуть необходимость по результатам сортировки отобразить небольшое итоговое сообщение. Сделать это легко, если воспользоваться возможностями утилиты awk. В следующем примере сведения о фильме с наименьшим объемом проката за год посредством канала направляются утилите awk, которая дополняет их поясняющим текстом. В качестве разделителя полей в обеих утилитах применяется двоеточие.
$ ~ sort -t: -k4 video.txt | head -1 | awk -F: '{print "Worst rental", $1, "has been rented", $3, "times"}'
Worst rental Alien has been rented 119 times
$ ~
Объединение двух отсортированных файлов
Прежде чем объединять два файла, их необходимо отсортировать, иначе результат будет не отсортированным. Предположим, имеется файл video_3.txt, содержащий дополнения к уже имеющемуся перечню фильмов, причем этот файл отсортирован (или не отсортирован):
$ ~ cat > video_3.txt
Crimson Tide:134:2031
Die Hard:152:2981
^C
$ ~ sort video_3.txt
Crimson Tide:134:2031
Die Hard:152:2981
$ ~
Необходимо объединить его с файлом video.txt. Для этого нужно применить команду sort с опцией -m в итоге получим объединенный и сортированный вариант:
$ ~ sort -t: -m -k1 video_3.txt video.txt
Boys in Company C:HK:192:2192
Alien:HK:119:1982
Crimson Tide:134:2031
Die Hard:152:2981
The Hill:KL:63:2972
Aliens:HK:532:4892
Star Wars:HK:301:4102
A Few Good Men:KL:445:5851
Toy Story:HK:239:3972
$ ~
Дополнительные примеры команды sort
Команда sort может применяться для сортировки имен пользователей в файле /etc/passwd. Достаточно выполнить сортировку содержимого этого файла по первому полю, которое включает регистрационные имена, а затем по каналу передать полученный результат утилите awk. Последняя отобразит содержимое только первого поля данного файла:
$ ~ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
.............................................................
$ ~ cat /etc/passwd | sort -t: -k1 | awk -F: '{print $1}'
_apt
arpwatch
avahi
backup
beef-xss
bin
colord
couchdb
daemon
Debian-exim
Debian-gdm
Debian-snmp
debian-spamd
debian-transmission
dell
dnsmasq
dradis
fetchmail
games
geoclue
....................................
$ ~ cat /etc/passwd | sort -t: -k1 | awk -F: '{print $1}'| cat -n | fold -w125
1 _apt
2 arpwatch
3 avahi
4 backup
5 beef-xss
6 bin
7 colord
8 couchdb
9 daemon
10 Debian-exim
11 Debian-gdm
12 Debian-snmp
13 debian-spamd
14 debian-transmission
15 dell
16 dnsmasq
17 dradis
18 fetchmail
19 games
20 geoclue
....................................
Команда sort может работать совместно с командой df, выводя на экран информацию об имеющихся файловых системах в порядке убывания процента используемого ими дискового пространства. Ниже приводится образец работы команды df и результат сортировки по полю 5, содержащему процент дискового пространства, занимаемого файловой системой, только предварительно с помощью редактора sed удалим первую строку. В процессе сортировки также воспользуемся опцией -b, которая позволяет игнорировать любое количество начальных пробелов.
$ ~ sudo df
Файловая система 1K-блоков Использовано Доступно Использовано% Cмонтировано в
dev 505636 0 505636 0% /dev
run 509256 740 508516 1% /run
/dev/sda1 20511356 11614124 7832272 60% /
tmpfs 509256 4 509252 1% /dev/shm
tmpfs 509256 0 509256 0% /sys/fs/cgroup
tmpfs 509256 36 509220 1% /tmp
/dev/sda2 38057472 30874952 5226272 86% /home
/dev/sda3 19091584 13087876 5010788 73% /mnt/Debian
/dev/sda4 17964924 10753644 6275652 64% /mnt/Kali
tmpfs 101848 0 101848 0% /run/user/0
tmpfs 101848 20 101828 1% /run/user/1000
$ ~ sudo df | sed '1d' | sort -b -r -k5
/dev/sda2 38057472 30874952 5226272 86% /home
/dev/sda3 19091584 13087876 5010788 73% /mnt/Debian
/dev/sda4 17964924 10753644 6275652 64% /mnt/Kali
/dev/sda1 20511356 11614124 7832272 60% /
tmpfs 509256 36 509220 1% /tmp
tmpfs 101848 20 101828 1% /run/user/1000
run 509256 740 508516 1% /run
tmpfs 509256 4 509252 1% /dev/shm
tmpfs 509256 0 509256 0% /sys/fs/cgroup
tmpfs 101848 0 101848 0% /run/user/0
dev 505636 0 505636 0% /dev
$ ~
Команда Column
К использованию команды sort можно добавить команду column. Разбивает стандартный ввод или файл на несколько колонок. Строки заполняются перед колонками; разделитель по-умолчанию - пробел.
Удаление повторяющихся строк с помощью команды UNIQ
Команда uniq применяется для удаления идущих подряд повторяющихся строк из текстового файла. Для правильного применения команды uniq важно, чтобы рассматриваемый файл был отсортирован. Однако это требование не является обязательным. Можно обращаться к произвольному не упорядоченному тексту и даже сравнивать отдельные фрагменты строк.
Эту команду можно рассматривать как вариант опции -u команды sort. Следует, однако, учитывать весьма важное отличие. Опция -u позволяет избавиться от всех одинаковых строк в файле, тогда как команда uniq обнаруживает повторяющиеся строки только в том случае, когда они следуют одна за другой. Если же на вход команды uniq подать отсортированный файл, то действие команд sort -u и uniq будет одинаковым. Рассмотрим пример, пусть имеется такой файл:
$ ~ cat > myfile.txt
May Day
May Day
May Day
Going Down
May Day
^C
$ ~
В данном случае команда uniq будет рассматривать первые три строки как повторяющиеся. Пятая строка таковой не считается, потому что не совпадает с четвертой строкой.
Синтаксис
Общий формат команды uniq таков: uniq опции входной_файл выходной_файл
Ниже перечислены некоторые из ее опций:
-u Отображение только не повторяющихся строк
-d Отображение одной копии каждой повторяющейся строки
-c Удаление повторяющихся строк с выводом перед каждой из оставшихся строк числа повторений
-f n Игнорирование первых п полей; полем считается последовательность непробельных символов, завершающаяся пробелом или табуляцией
В некоторых системах опция -f не распознается, в этом случае вместо нее следует использовать опцию -n, где n - номер поля.
Давайте применим команду uniq к показанному выше файлу myfile.txt.
$ ~ uniq myfile.txt
May Day
Going Down
May Day
$ ~
Как уже говорилось, последняя строка не считается повторяющейся. Если же выполнить над файлом команду sort -u, будут получены только две строки:
$ ~ sort -u myfile.txt
Going Down
May Day
$ ~
Определение количества повторений
Указав в команде uniq опцию -c, можно не только отбросить повторяющиеся строки, но и узнать, сколько раз повторяется каждая строка. В следующем примере команда uniq сообщает о том, что первая строка "May Day" встречается три раза подряд:
$ ~ uniq -c myfile.txt
3 May Day
1 Going Down
1 May Day
$ ~
Отображение только повторяющихся строк
Опция -d позволяет отобразить только те строки, которые встречаются несколько раз подряд:
$ ~ uniq -d myfile.txt
May Day
$ ~
Проверка уникальности отдельных полей
Команда uniq позволяет разбивать файл на поля, разделенные пробелами, с тем чтобы можно было исключать требуемые поля из процедуры проверки. Ниже показан небольшой файл, содержащий две колонки текста, причем содержимое второго поля в каждой строке одинаковое:
$ ~ cat > parts.txt
AK123 OP
OК122 OP
OК999 OP
^C
$ ~
Если к этому файлу применить команду uniq, будут отображены все строки, поскольку все они разные.
$ ~ uniq parts.txt
AK123 OP
OК122 OP
OК999 OP
$ ~
Если же выполнить проверку только по второму полю, получим иной результат. Команда uniq сравнит повторяющиеся поля "ОР" и отобразит только одну строку:
$ ~ uniq -f1 parts.txt
AK123 OP
$ ~
Объединение файлов с помощью команды JOIN
Команда join выполняет соединение строк из двух текстовых файлов на основании совпадения указанных полей. Ее действие напоминает операцию join языка SQL. Механизм работы команды таков:
Каждый из двух входных файлов разбивается на поля (по умолчанию разделителем полей является пробел).
Из первого файла извлекается первая строка, а из нее — первое поле (можно указать другое поле).
Во втором файле ищется строка, имеющая такое же первое поле.
Найденная строка, из которой удаляется первое поле, присоединяется к исходной строке, и результат записывается в выходной поток.
Пункты 3 и 4 повторяются до тех пор, пока во втором файле есть строки с совпадающим первым полем.
Пункты 2—6 повторяются для каждой строки первого файла.
Таким образом, в выходной поток попадают только строки, имеющие общие компоненты.
Общий формат команды join таков: join [опции] входной_файл1 входной_файл2
Некоторые наиболее важные опции команды:
Объединение двух файлов
Предположим, имеется два текстовых файла: один называется names.txt и содержит имена пользователей с указанием улиц, на которых они проживают, а другой называется town.txt и содержит имена пользователей с указанием городов, в которых они живут.
$ ~ cat > names.txt
M.Golls 12 Hidd Rd
P.Heller The Acre
P.Willey 132 The Grove
T.Norms 84 Connaught Rd
K.Fletch 12 Woodlea
^C
$ ~ cat > town.txt
M.Golls Norwich NRD
P.Willey Galashiels GDD
T.Norms Brandon BSL
K.Fletch Mildenhall MAF
^C
$ ~
Задача состоит в таком соединении двух файлов, чтобы итоговый файл содержал имена пользователей и их полные адреса. Очевидно, что общим полем является первое.
Команда join по умолчанию выполняет объединение файлов именно по первому полю.
$ ~ join names.txt town.txt
M.Golls 12 Hidd Rd Norwich NRD
P.Willey 132 The Grove Galashiels GDD
join: names.txt:5: is not sorted: K.Fletch 12 Woodlea
join: town.txt:4: is not sorted: K.Fletch Mildenhall MAF
T.Norms 84 Connaught Rd Brandon BSL
K.Fletch 12 Woodlea Mildenhall MAF
join: input is not in sorted order
$ ~
Почему возникла ошика, ошибка возникла от того что join требует , чтобы файлы были отсортированы лексически, поэтому в нашем случае надо применить опцию --nocheck-order
$ join --nocheck-order names.txt town.txt
M.Golls 12 Hidd Rd Norwich NRD
P.Willey 132 The Grove Galashiels GDD
T.Norms 84 Connaught Rd Brandon BSL
K.Fletch 12 Woodlea Mildenhall MAF
$ https://www.gnu.org/manual/General-options-in-join
Для пользователя P.Heller, нет строки в файле town.txt, и по этой причине в результаты работы команды join он не попал
Включение не совпадающих строк
Если требуется все‑таки включить информацию о пользователе P. Heller в выходные данные, воспользуйтесь опцией -a. Поскольку исходная строка находится в первом файле, параметром данной опции будет цифра 1:
$ join --nocheck-order -a1 names.txt town.txt
M.Golls 12 Hidd Rd Norwich NRD
P.Heller The Acre
P.Willey 132 The Grove Galashiels GDD
T.Norms 84 Connaught Rd Brandon BSL
K.Fletch 12 Woodlea Mildenhall MAF
$
В общем случае, чтобы включать в результаты не совпадающие строки из обоих файлов, применяйте команду join -a1 -a2.
Задание формата вывода
Опция -o позволяет указать, какие поля и в какой последовательности следует включать в формируемую строку. Допустим, нужно создать файл, который включает только имена пользователей и названия городов, в которых они проживают. Требуемая информация содержится в первом поле первого файла и втором поле второго файла. Соответствующая команда имеет следующий вид:
$ join --nocheck-order -o 1.1,2.2 names.txt town.txt
M.Golls Norwich
P.Willey Galashiels
T.Norms Brandon
K.Fletch Mildenhall
$
Выбор ключевого поля
He всегда первое поле является общим для обоих файлов. Рассмотрим пример. Имеются два файла:
$ ~ cat > pers
P.Jones Office Runner ID897
S.Round UNIX admin ID667
L.Clip Personl Chief ID982
^C
$ ~ cat > pers2
Dept2C ID897 6 years
Dept3S ID667 2 years
Dept5Z ID982 1 year
^C
$
Файл pers содержит имена, названия должностей и личные идентификационные номера служащих фирмы. Файл pers2 содержит для каждого из служащих код отдела, в котором он работает, идентификационный номер и стаж работы на фирме. В данном случае требуется выполнить соединение строк по номеру служащего. Он хранится в четвертом поле первого файла и во втором поле второго файла. Задать их в команде join можно с помощью опции -n m, где n — номер файла, a m — номер поля. Ниже приведена соответствующая команда и результат ее выполнения:
$ ~ join -1 4 -2 2 pers pers2
ID897 P.Jones Office Runner Dept2C 6 years
ID667 S.Round UNIX admin Dept3S 2 years
ID982 L.Clip Personl Chief Dept5Z 1 year
$ ~
При работе с командой join следует быть внимательным, вычисляя номер нужного поля. Можно посчитать, что доступ реализуется к полю 4, а с точки зрения команды join это поле 5. В итоге будут получены неправильные результаты. Чтобы проверить, содержит ли поле с указанным номером предполагаемые данные, воспользуйтесь утилитой awk:
$ awk '{print $4}' имя_файла
$ ~ awk '{print $1}' pers
P.Jones
S.Round
L.Clip
$ ~ awk '{print $4}' pers2
years
years
year
$ ~
Вырезание текста с помощью команды CUT
Команда cut позволяет вырезать фрагменты строк из текстовых файлов или из стандартного входного потока. Извлеченный подобным образом текст направляется в стандартный выходной поток. Общий формат команды cut таков: cut [опции] файлы…
Основные опции этой команды:
Параметр список в опциях -c и -f представляет собой разделенный запятыми список диапазонов символов или полей соответственно. Диапазон может быть задан в одной из четырех форм:
-n В выходной поток включается каждый n–й символ (поле) каждой строки каждого входного файла
n- Диапазон формируется от n–го символа (поля) до конца строки
n–m Диапазон формируется от n–го символа (поля) до m–го символа (поля) включительно
-m Диапазон формируется от начала строки до m–го символа (поля)
Задание разделителя полей
В качестве входного файла мы возьмем файл pers из предыдущего примера, только на этот раз поля в нем будут разделены двоеточием.
$ ~ cat pers
P.Jones:Office Runner:ID897
S.Round:UNIX admin:ID667
L.Clip:Personl Chief:ID982
$
Предположим, необходимо извлечь из файла список идентификационных номеров служащих, находящийся в третьем поле. Вот как можно это сделать:
$ ~ cut -d: -f3 pers
ID897
ID667
ID982
$
Опция -d: говорит о том, что поля в файле разделяются двоеточием.
Опция -f 3 задает выборку третьего поля.
Если требуется вырезать несколько полей, необходимо перечислить их в опции -f. Например, показанная ниже команда формирует список служащих с их идентификационными номерами:
$ ~ cut -d: -f1,3 pers
P.Jones:ID897
S.Round:ID667
L.Clip:ID982
А вот как можно извлечь из каталога /etc/passwd регистрационные имена пользователей и имена их начальных каталогов, хранящиеся в полях 1 и 6 соответственно:
$ ~ cut -d: -f1,6 /etc/passwd
root:/root
bin:/bin
daemon:/
mail:/var/spool/mail
ftp:/srv/ftp
http:/srv/http
Какая служба использует порт <n>:
$ grep -w 21 /etc/services | cut -f 1 | uniq
ftp
fsp
Вырезание отдельных символов
Опция -c позволяет указывать, какие конкретно символы необходимо извлекать из каждой строки входного потока. Применять эту опцию следует в том случае, если вы имеете дело со строками фиксированной длины Рассмотрим такой пример:
Когда в мою систему поступают файлы сообщений, я просматриваю их имена для определения источника, из которого они были получены. На основании этой информации производится сортировка файлов по каталогам. Идентификатор источника содержится в последних трех символах имени файла. Вот примерный список имен файлов:
2231DG
2232DP
2236DK
Извлечение идентификаторов осуществляется с помощью такой команды:
$ 1s 223* | cut -с4-6
1DG
2DP
6DK
Показанная ниже команда возвращает список пользователей, зарегистрированных в данный момент в системе:
$ ~ who | cut -c1-8
user
$ ~
cut sort xargs
Пример того, как вывести всех пользователей системы:
$ ~ cut -d: -f1 < /etc/passwd | sort | xargs
avahi bin colord daemon dbus fetchmail ftp http iarch incron mail mysql nobody polkitd root rtkit systemd-bus-proxy systemd-coredump systemd-journal-gateway systemd-journal-remote systemd-journal-upload systemd-network systemd-resolve systemd-timesync usbmux uuidd
$ ~
$ ~ cut -d: -f1 < /etc/passwd | sort | xargs | awk 'BEGIN {print "Users Name\n------------ "} {print $0} \
END {print "end-of-report"}'
Users Name
------------
avahi bin colord daemon dbus fetchmail ftp http iarch incron mail mysql nobody polkitd root rtkit systemd-bus-proxy systemd-coredump systemd-journal-gateway systemd-journal-remote systemd-journal-upload systemd-network systemd-resolve systemd-timesync usbmux uuidd
end-of-report
$ ~
О команде xarg, ниже более подробно.
Вставка текста с помощью команды PASTE
С помощью команды cut отдельные символы и целые поля извлекаются из текстовых файлов или стандартного входного потока. Команда paste выполняет противоположное действие: она вставляет в выходной поток содержимое входных файлов. Прежде чем вставлять данные из разных источников, следует убедиться, что они содержат равное число строк, иначе будут сформированы неполные строки,
Команда paste объединяет строки с одинаковыми номерами: сначала берутся первые строки из каждого файла и объединенная строка записывается в выходной поток, затем берутся вторые строки, третьи и т. д. По умолчанию разделителем полей является символ табуляции, если только не указана опция -d, которая позволяют задать иной разделитель.
Формат команды paste таков: paste [опции] файл…
Опции команды paste:
Определение порядка вставки столбцов
Для иллюстрации процедуры вставки обратимся к следующим двум файлам:
$ ~ cat > pas_1
ID897
ID667
ID9B2
^C
$ ~ cat > pas_2
Jones
Round
Clip
^C
$
По умолчанию команда paste вставляет столбцы один за другим:
$ ~ paste pas_1 pas_2
ID897 Jones
ID667 Round
ID9B2 Clip
$ ~
Порядок задания файлов в командной строке играет вот какую роль:
$ ~ paste pas_2 pas_1
Jones ID897
Round ID667
Clip ID9B2
$ ~
Выбор разделителя полей
Если требуется создать выходной файл, в котором разделителем полей будет какой‑то другой символ вместо табуляции, воспользуйтесь опцией -d. В приведенном ниже примере строки объединяемых файлов разделяются двоеточием:
$ ~ paste -d: pas_2 pas_1
Jones :ID897
Round :ID667
Clip:ID9B2
$ ~
Слияние строк
Наличие опции -s заставляет команду paste работать немного по - другому: для каждого входного файла она выполняет слияние всех его строк, записывая результат в выходной поток. Представленная ниже команда сначала отображает все имена служащих, а затем - их идентификационные номера.
$ ~ paste -s pas_2 pas_1
Jones Round Clip
ID897 ID667 ID9B2
$ ~
Чтение данных из стандартного входного потока
Команда paste имеет удобную опцию - (дефис), которая позволяет принимать данные из стандартного входного потока. Каждый дефис в командной строке соответствует одной колонке выходных данных. Например, список файлов каталога можно отобразить в четырех колоночном формате, как показано ниже:
$ ~ls | paste - - - -
Если же нужно отобразить список в одну колонку, воспользуйтесь такой командой:
$ ~ ls | paste -
Все это можно совместить с ключом -d определив другой символ вместо табуляции
$ ~ ls | paste -d@ - - -
Разделение файла на части с помощью команды SPLIT
Команда split позволяет разделять крупные текстовые файлы на более мелкие, Это может оказаться удобным, например, при передаче файлов по сети. Общий формат команды split таков: split [-размер_выходного_файла] входной_файл [префикс]
Первый параметр определяет количество строк, на которое нужно разбить файл. По умолчанию файл разбивается на фрагменты по 1000 строк. Если размер файла не кратен 1000, последний фрагмент будет содержать менее 1000 строк. Например, из файла, содержащего 2800 строк, в результате выполнения данной команды образуются три файла, включающих соответственно 1000, 1000 и 800 строк.
Имя каждого созданного файла представляется в формате от префикс[аа] до префикс[zz]. По умолчанию префиксом является буква 'x'. Таким образом, команда split создает такую последовательность файлов:
хаа, xab, … xzy, xzz
Если расположить файлы в алфавитном порядке и выполнить их последовательную конкатенацию, получим исходный файл. (лат. concatenatio «присоединение цепями; сцепление») — операция склеивания объектов линейной структуры, обычно строк.
Следующий пример поможет разъяснить сказанное. Допустим, имеется файл bigone.txt, содержащий 2800 строк. В результате выполнения команды split будут сформированы три выходных файла:
Имя файла Размер
xaa 1000
xab 1000
xac 800
Теперь рассмотрим, как изменить размер создаваемых файлов. Ниже показан файл split1, содержащий шесть строк:
$ ~ cat > split_1
this ls line1
this ls line2
this ls line3
this ls line4
this ls line5
this ls line6
^C
$
Для разделения его на фрагменты по две строки в каждом файле воспользуемся такой командой: $ split -2 split1 и проверим, что было создано (команда ls -lt сортирует список файлов по дате создания, а команда head отбирает из этого списка первые десять элементов):
$ ~ split -2 split_1
$ ~ ls -lt | head
итого 15848
-rw-r--r-- 1 iarch users 30 май 15 18:17 xaa
-rw-r--r-- 1 iarch users 30 май 15 18:17 xab
-rw-r--r-- 1 iarch users 29 май 15 18:17 xac
-rw-r--r-- 1 iarch users 89 май 15 18:16 split_1
.........................................
$
Исходный файл состоит из шести строк. В результате применения к нему команды split были сформированы три файла, содержащих по две строки каждый. Чтобы убедиться в правильности работы команды, рассмотрим содержимое файла хаc, который должен включать последние две строки:
$ cat xaa
this ls line1
this ls line2
$ cat xab
this ls line3
this ls line4
$ cat xac
this ls line5
this ls line6
$
Форматирование текста по ширине
Иногда возникает необходимость "жестко" отформатировать текст по ширине, чтобы каждая строка переносиласьпо такой-то позиции справа. Для этого можно воспользоваться стандартной командой fold, задав ее в командной строке в следующем формате: fold --width=ширина_строки -s исходный_файл > файл_вывода
Например: fold --width=72 -s my.txt > my_formatted_text.txt
Здесь мы задали ширину строки в 72 символа. Обрабатывается файл my.txt. Результат записывается в файл my_formatted_text.txt.
***Параметр -s нужен для того, чтобы перенос строки осуществлялся по словам, а не по символам.
Утилита tr
https://www.ibm.com/developerworks/ru.html
Утилита tr выполняет символьное преобразование путем подстановки или удаления символов из стандартного входного потока. Она часто применяется для удаления управляющих символов из файла или преобразования регистра символов. Как правило, утилите tr передаются две строки: первая строка содержит искомые символы, а вторая — те, на которые их следует заменить. При запуске команды устанавливается соответствие между символами обеих строк, а затем начинается преобразование.
Формат утилиты tr с наиболее часто применяемыми параметрами таков: tr -c -d -s ["строка1"] ["строка2"] входной_файл где:
-c Задает замену набора символов, указанных в строке1 их собственным дополнением при условии, что значение этих символов находится в диапазоне значений кодов ASCII
-d Задает удаление во входном файле всех символов, указанных в строке1
-s Задает удаление в последовательности повторяющихся символов всех символов, кроме первого, благодаря чему удаляются повторяющиеся символы
-d Используется для удаления из текста символов, перечисленных в наборе ["строка1"]. Опция может удалять также специальные символы, например символ возврата каретки, который заканчивает строку в паре с символом новой строки в файлах ОС Windows. После его удаления останется только символ новой строки.
Параметр входной_файл определяет имя файла, содержимое которого необходимо преобразовать. Несмотря на то,что входные данные могут иметь и другие формы, широко используется именно указанный выше способ их задания.
Диапазоны символов
При использовании утилиты tr можно указать диапазоны или списки символов в виде шаблонов, которые образованы строками. Эти шаблоны подобны регулярным выражениям, однако на самом деле они таковыми не являются. При указании в утилите tr содержимого строк строка1 или строка2 используются только диапазоны и последовательности символов либо отдельные символы:
[a-z] Строка символов, находящихся в диапазоне a-z
[A-Z] Строка символов, находящихся в диапазоне A-Z
[0-9] Строка чисел
/octal Восьмеричное число, состоящее из трех чисел и представляющее любой действительный символ в коде ASCII
[0*n] Означает символ '0', встречающийся столько раз, сколько указывает значение 'n'. Таким образом, [0*2] означает 00, причем в любой строке, включая и 00
В большинстве вариантов утилиты tr поддерживаются классы символов и сокращенная запись управляющих символов. В формат класса символов [:class:] среди прочего входят следующие обозначения:
alnum (буквенно–цифровые символы),
alpha (буквы),
blank (пропуски),
upper (прописные буквы),
lower (строчные буквы),
cntrl (управляющие символы),
space (пробелы),
digit (цифры),
graph (графические символы) и т. д.
Различные способы указания управляющих символов в утилите tr:
Таблица соответствия кодов - представлений чисел: ASCII Char_1 ASCII Char_2
Управляющие символы ANSI (ANSI escape-code,управляющие-последовательности) — символы, встраиваемые в текст, для управления форматом, цветом и другими опциями вывода в текстовом терминале. Почти все эмуляторы терминалов, предназначенные для отображения текстового вывода с удалённого компьютера и (за исключением Microsoft Windows) для отображения текстового вывода локального программного обеспечения, способны интерпретировать по крайней мере некоторые управляющие последовательности ANSI.
ASCII (American standard code for information interchange,) — название таблицы (кодировки, набора), в которой некоторым распространённым печатным и непечатным символам сопоставлены числовые коды. Таблица была разработана и стандартизована в США, в 1963 году. Управляющие символы — символы в кодировке, которым не приписано графическое представление, но которые используются для управления устройствами, организации передачи данных и других целей. Сейчас для этих целей применяются форматы файлов, языки управления устройствами (такие как Postscript) и сетевые протоколы. Поэтому многие управляющие символы сейчас или не используются вообще, или используются не по назначению. Стандарт POSIX требует обязательного наличия лишь восьми управляющих символов — \0, \a, \b, \t, \n, \v, \f, \r
При замене строки или диапазона символов одним символом следует иметь в виду, что этот символ не указывается в квадратных скобках ([]). В некоторых системах допускается применение квадратных скобок, причем в данном случае можно для указания символа новой строки воспользоваться шаблоном ["\012"] или "\012". Утилита tr не предъявляет строгих требований к виду кавычек. Поэтому не следует удивляться, если эта утилита действует даже в том случае, если вместо одинарных кавычек используются двойные кавычки.
Подобно большинству системных инструментальных средств, утилита tr восприимчива к специальным символам. Поэтому если требуется выполнить сопоставление с одним из таких символов, следует предварительно отделить этот символ обратной косой чертой. Например, для указания левой фигурной скобки ({) необходимо ввести \{ для отмены специального значения фигурной скобки.
Сохранение выходного результата
Если нужно сохранить полученные результаты, следует переадресовать их в файл. В приведенном ниже примере выходной результат перенаправляется в файл с именем results.txt. В качестве входного используется файл oops.txt. : $ tr -s "[a-z]" < oops.txt > results.txt
Некоторые примеры использования:
Устранение повторяющихся символов
Если проанализировать приведенный ниже файл, можно обнаружить некоторые опечатки.
$ pg oops.txt
And the cowwwwws went homeeeeeeee
Or did theyyyy
Если нужно избавиться от повторяющихся букв или сократить число подобных букв до одной, можно воспользоваться параметром ' -s'. Также можно воспользоваться шаблоном [a-z], поскольку в данном случае все символы являются буквенными. При этом входной файл перенаправляется команде tr.
$ tr -s "[a-z]"< oops.txt
And the cows went home
Or did they
Все повторяющиеся символы устраняются. При необходимости файл oops.txt можно перенаправить с помощью команды cat. Результат будет тот же.
$ cat oops.txt | tr -s "[a-z]"
And the cows went home
Or did they
Преобразование прописных букв в строчные
Изменение регистра символов является наряду с процедурой удаления управляющих символов одним из наиболее распространенных случаев применения утилиты tr. Чтобы выполнить подобное преобразование, достаточно указать шаблон строчных букв '[a-z]' для входных данных и шаблон прописных букв '[A-Z]' для выходных преобразованных данных.
В первом примере осуществляется передача утилите tr строки, содержащей смешанный набор символов.
$ echo "May Day, May Day, Going Down.." | tr "[a-z]" "[A-Z]"
MAY DAY, MAY DAY, GOING DOWN..
С другой стороны, можно воспользоваться классами символов [:lower:] и [:upper:].
$ echo "May Day, May Day, Going Down.." | tr "[:lower:]" "[:upper:]"
MAY DAY, MAY DAY, GOING DOWN..
Для преобразования прописных букв из текстового файла в строчные и последующего их размещения в новом файле применяется следующий формат:
cat file-to-translate | tr "[A-Z]" "[a-z]" > new-file-name
где параметр 'файл–для–преобразования' — преобразуемый файл, а 'имя–нового–файла' — имя, которое нужно присвоить новому файлу. Например:
cat myfile | tr "[A-Z]" "[a-z]" > lower_myfile
Преобразование управляющих символов
Чаще всего утилита tr применяется для преобразования управляющих символов, особенно во время загрузки файлов из DOS в UNIX. Если в команде ftp не задан параметр, выполняющий преобразование символов возврата каретки в символы новой строки, обычно применяют утилиту tr.
Ниже приведен текстовый файл, при пересылке которого не было выполнено преобразование символов возврата каретки. Файл содержит часть требования на выдачу канцелярских принадлежностей. Управляющие символы файла отображены ниже с помощью команды cat -v.
$ cat -v stat.txt
Boxes рарег^^^^^^12^M
Clips metal^^^^^^^50^M
Pencils?medium^^^^^^10^M
^Z
В этом файле последовательность символов '^^^^^^' кодирует символы табуляции, каждая строка завершается управляющей последовательностью Control-M, а в конце файла находится управляющая последовательность Control-Z. Ниже показано, как можно исправить положение.
В данном случае придется воспользоваться параметром '-s'. Если обратиться к таблице кодов ASCII, то восьмеричный код символа '^' равен 136. Соответствующее значение для управляющей последовательности ^M равно '015', для символа табуляции — '011', а для управляющей последовательности ^Z — '032'. Данная задача выполняется поэтапно.
Для замены в рассматриваемой команде последовательности символов '^^^^^^' символами табуляции используется следующий шаблон: "\136" "[\011*]". Затем полученные результаты перенаправляются во временный рабочий файл с именем stat.tmp.
$ tr -s '[\136]" "[\011*]" < stat.tr > stat.tmp
Boxes paper 12^M
Clips metal 50^M.
Pencils?medium 10^М
^Z
Для замены управляющих последовательностей ^M, расположенных в конце каждой строки, символом новой строкии устранения управляющей последовательности ^Z применяется шаблон \n. Не следует забывать, что входные данные поступают из временного файла stat.tmp.
$ tr -s "[\015\032]" "\n" < stat.tmp
Boxes paper 12
Clips metal 50
Pencils-medium 10
Таким образом, управляющие символы удаляются и файл готов к применению.
Сравнение с несколькими символами
Для выполнения сравнения с несколькими символами применяется формат [character*n]. Ниже приводится содержимое файла, описывающего жесткие диски системы. В файле содержатся диски, которые зарегистрированы или распознаны системой. Первый столбец содержит числа. Если этот столбец не состоит из одних нулей, то регистрируется соответствующий диск во втором столбце.
Иногда надоедает наблюдать в подобных списках нули, поэтому заменим их символом, который привлекает к себе внимание. Тогда сразу становится видно, какие диски присутствуют в системе, а какие -oтсутствуют. Ниже приведена часть содержимого файла.
$ cat > hdisk.txt
1293 hdisk3
4512 hdisk12
0000 hdisk5
4993 hdisk12
2994 hdisk7
^C
При просмотре файла становится ясно, что имеется один жесткий диск, который не зарегистрирован. Для замены всех нулей, допустим, звездочками можно воспользоваться шаблоном [0*4], который означает поиск соответствия, по крайней мере, четырем нулям. При этом строка замены содержит только звездочки. Ниже приводится соответствующая команда и результат выполнения подобной фильтрации:
$ tr "[0*4]" "*" < hdisk.txt
1293 hdisk3
4512 hdisk12
**** hdisk5
4993 hdisk12
2994 hdisk7
Теперь, просматривая приведенный выше файл, можно сразу узнать, какой диск не зарегистрирован в системе.
Удаление пустых строк
Для удаления пустых строк их следует просто "вытеснить" из файла. Ниже приведен файл с именем plane.txt, содержащий ряд пустых строк.
$ pg plane.txt
987932 Spitfire
190992 Lancaster
238991 Typhoon
В данном случае применяется параметр ' -s', который приводит к удалению пустых строк. Также используется восьмеричное значение для символа новой строки \012. Ниже приведена соответствующая команда.
$ tr -s "[\012]" < plane.txt
987932 Spitfire
190992 Lancaster
238991 Typhoon
С другой стороны, можно воспользоваться сокращенной записью символа новой строки ' \n'. Можно применять как одинарные, так и двойные кавычки, хотя обычно используются двойные кавычки.
$ tr -s "[\n]" < plane.txt
987932 Spitfire
190992 Lancaster
238991 Typhoon
Преобразование строчных букв в прописные
Преобразование строчных букв в прописные выполняется в обратном порядке по сравнению с преобразованием, рассмотренным в предыдущем разделе. Ниже приведены два примера подобного преобразования.
$ echo "Look for the route, or make the route" | tr "[a-z]" "[A-Z]"
LOOK FOR THE ROUTE, OR MAKE THE ROUTE
$ echo "May Day, May Day, Going Down.." | tr "[:lower:]" "[:upper:]"
MAY DAY, MAY DAY, GOING DOWN..
Для преобразования строчных букв из текстового файла в прописные и последующего их размещения в новом файле применяется формат:
cat file-to-translate | tr "[a-z]" "[A-Z]" > new-file-name
где 'файл–для–преобразования' - преобразуемый файл, а 'имя–нового–файла' — имя, которое нужно присвоить новому файлу. Например:
cat myfile | tr "[a-z]" "[A-Z]" > upper_myfile
Удаление определенных символов
Иногда возникает необходимость в удалении некоторых столбцов из загруженного файла, содержащего только буквы и числа. Для этого в рассматриваемой команде необходимо применить оба параметра, '-с' и '-s'.
Приведенный ниже файл содержит часть составленного на неделю личного календаря. Задача заключается в устранении чисел. В личном календаре остаются в наличии только дни недели. Поскольку дни недели используются в формате как прописных, так и строчных букв, в этом случае применяют оба диапазона символов: [a-z] и [A-z]. При этом команда 'tr -cs "[a-z] [A-z]" "[\012*]"' выбирает все содержимое файла, которое не находится в пределах [a-z] или [A-Z] (буквенных символов), содержащихся в строка1, и преобразует их в символы новой строки. В приведенной выше команде tr параметр ' -s' сообщает о необходимости "сокращения" всех символов новой строки, а параметр '-с' сохраняет без изменения все буквенные символы. Ниже приведен файл, содержащий данные личного календаря, после чего следует строка с утилитой tr и результат ее выполнения.
$ cat > diary.txt
monday 10:50
Tuesday 15:30
wednesday 15:30
thurday 10:30
Friday 09:20
^C
$ tr -cs "[a-z][A-Z]" "[\012*]" < diary.txt
monday
Tuesday
wednesday
thurday
Friday
$
Быстрые преобразования
Если из файла необходимо удалить только управляющие последовательности ^M и заменить их символами новой строки, для этого применяется команда:
$ tr -s "[\015]" "\n" < файл_ввода
С другой стороны, для получения аналогичного результата можно воспользоваться командой:
$ tr -s "[\r]" "[\n]" < файл_ввода
То же самое преобразование можно выполнить и с помощью команды:
$ tr -s "\r" "\n" < файл_ввода
Еще один распространенный вариант преобразования файлов, перенесенных из DOS в UNIX, иллюстрирует команда:
$ tr -s "[\015\032]" "[\012*]" < файл_ввода
Эта команда удаляет управляющие последовательности ^M и ^Z и заменяет их символами новой строки.
Следующая команда удаляет символы табуляции, заменяя их пробелами:
$ tr -s "[\011]" "[\040*]" < файл_ввода
Для замены в файле пароля passwd всех двоеточий символами табуляции, двоеточие следует заключить в кавычки и указать в строке замены восьмеричное значение символа табуляции, которое равно '011'. Файл станет более удобным для чтения. Сначала приводится файл passwd, а затем команда с утилитой tr, которая выполняет задачу.
$ pg passwd
halt:*:7:0:halt:/sbin:/sbin/halt
mail:*:8:12.mail:/var/spool/mail:
news:*:9:13:news:/var/spool/news:
uucp:*:10:14:tmcp:/var/spool/uucp:
$ tr -s "[:]" "[\011]" < /etc/passwd
halt * 7 0 halt /sbin /sbin/halt
mail * 8 12 mail /var/spool/mail
news * 9 13 news /var/spool/news
uucp * 10 14 uucp /var/spool/uucp
С другой стороны, аналогичного результата можно добиться с помощью следующей команды, где указывается сокращенная запись символа табуляции:
$ tr "[:]" "[\t]" < /etc/passwd
Утилита tr применяется, главным образом, для преобразования символов и удаления управляющих символов. Все приведенные примеры, могут быть реализованы и с помощью команды sed. Однако многие предпочитают применять утилиту tr, поскольку она выполняет те же задачи и более "проста" в применении. Трудно предсказать, какое применение команде может найти пользователь, знающий ее тонкости. Особенно полезной может быть команда в качестве фильтра в составе программных каналов (pipes).
Использование XARGS
http://ant0.ru/sed1line.html <<------- SED on line Eric Pement (RU)
http://www.pement.org/sed/sed1line.txt <<------- SED on line Eric Pement
http://www.pement.org/awk/awk1line.txt <<------- AWK on line Eric Pement
Передача данных в stdin (на практике аргументов) — xargs (parallel , parallel) — была(были) разработана в течение 2002-2005 годов и основаны на работе Кэмерона Симпсона, xargs своего рода "конструктор", конструирует команду из данных входного потока и выполняет ее, точнее позволяет вызвать любую команду с аргументами, взятыми из стандартного входа. Причём аргументы можно передать все сразу, а можно группировать по несколько штук, команда объединяет зафиксированный набор заданных в командной строке начальных аргументов с аргументами, прочитанными со стандартного ввода, и выполняет указанную команду один или несколько раз.
Кратко: xargs — формирование списка аргументов и выполнение команды.
Число аргументов, которые должны быть прочитаны для каждого вызова команды, и способ, которым они объединяются, определяются заданными опциями. Количество примеров применения зависит от фантазии, владением утилитами, командами, синтаксисом и т.д, использование утилиты может значительно оптимизировать вашу работу.
Простейшая конструкция xargs с использованием канала : [команда генератор списка] | xargs [опции] [команда] Как писалось выше (и это основное) xargs обрабатывает входящий поток и делит его на аргументы, вопрос как ?:
Аргументы, прочитанные со стандартного ввода (дополнительные аргументы), - это непрерывный поток символов, разделенный одним или несколькими пробелами, символами табуляции или переводами строки, пустые строки игнорируются.
Чтобы включить в аргумент пробелы и табуляции, их надо выделить символами обратного слеша или кавычками (об этом ниже), символы, заключенные в кавычки (одинарные или двойные) воспринимаются буквально сами кавычки удаляются. Вне цепочек в кавычках обратный слеш вместе со следующим символом обозначает соответствующий управляющий символ, любой одиночный символ, включая символы перевода строки, может быть экранирован обратным слэшем..
Конструирование каждого списка аргументов начинается с НАЧАЛЬНЫХ-АРГУМЕНТОВ , за ними следуют аргументы со стандартного ввода, дополнительные аргументы (то есть аргументы полученные в результате разбора потока, кроме исключений: см. опцию -i).
Опции -i, -l и -n определяют, как выбирать аргументы для каждого вызова команды. Когда ни одна из этих опций не указана, за начальными аргументами следует несколько аргументов, прочитанных подряд со стандартного ввода до заполнения внутреннего буфера, затем выполняется команда с накопленными аргументами. Данный процесс повторяется до тех пор, пока все аргументы не будут исчерпаны.
Если указаны взаимоисключающие опции (например, одновременно заданы опции -l и -n), берется во внимание последняя и в итоге команда xargs соберет аргументы со стандартного ввода, разделенные пробелом или переводом строки.
Чтобы группировать аргументы, можно использовать двойные или одинарные кавычки. Можно также указать разделитель с помощью опции -d, если команде xargs не передать вообще никаких аргументов, то по умолчанию будет выполнена команда /bin/echo.
И на словах вроде как все ясно, однако на деле ясно далеко не все, попробуем на примере текстового файла (назовем его ASCII - файлом, пытаясь подчеркнуть важность употребления пробелов, символов табуляции, перевода строки и пр.) который и будет создавать этот самый поток аргументов разобраться в некоторых (увы не всех) принципах конструирования, формирования списка аргументов, пример далеко не "блестящий", но и он возможно (отчасти) прояснит тьму невежества, вообще что бы полноценно работать с xargs, то есть самостоятельно создавать некие сложные конструкции придется не много пораскинуть мозгами, но обычно этим ни кто не занимается, а все пользуются готовыми шаблонами из "инета" редактируя их под свои цели, так поступаю и я, поэтому ниже попытаюсь собирать готовые примеры использования этой действительно весьма полезной утилиты. Итак создадим файл:
$ cat > args.txt
'arg1'
arg2 spase
"arg3 space"
'arg4 quoted'
arg5
'"arg6 arg7"'
`" "`'' ``
`arg8-arg9-arg10`
\"arg11 arg12\"
^C
$
$ cat -n args.txt
1 'arg1'
2 arg2 spase
3 "arg3 space"
4 'arg4 quoted'
5 arg5
6 '"arg6 arg7"'
7 `" "`'' ``
8 `arg8-arg9-arg10`
9
10
11 \"arg11 arg12\"
$
Для наглядности создадим скрипт который выделит аргументы в фигурные скобки:
$ ~ cat v_args
#!/bin/bash
echo -n "{total-$#}" # общее кол-во аргументов
while [[ $1 != "" ]]; # в цикле сравнение того что аргумент не пустой начиная с arg1
do
echo -n "{$1}"; # заключить при выводе в скобки
shift; # "сдвиг". в циклах For и While применяются для передачи значения из предыдущей итерации в следующую
done
echo
$ ~
Выполним без скрипта, демонстрируя опцию -а (читать из файла , а не из stdin):
$ xargs -a args.txt
arg1 arg2 spase arg3 space arg4 quoted arg5 "arg6 arg7" ` ` `` `arg8-arg9-arg10` "arg11 arg12"
$
Не впечатляет!..., со скриптом:
Сначала добавив домашний каталог в переменную $PATH
$ export PATH=$PATH:~;
$ echo $PATH
/usr/local/sbin:/usr/sbin:........../home/user
Сделаем скрипт исполняемым:
$ chmod +x v_args
Выполним:
$ cat args.txt | xargs v_args
{total-12}{arg1}{arg2}{spase}{arg3 space}{arg4 quoted}{arg5}{"arg6 arg7"}{` `}{``}{`arg8-arg9-arg10`}{"arg11}{arg12"}
$
Отсортируем по строкам добавив (sed 's/}/&\n/g'), пронумеруем и сравним два файла (предполагаемый stdin и сформированный список аргументов):
$ cat args.txt | xargs v_args | sed 's/}/&\n/g' | nl
$ cat -n args.txt
И в итоге: Утилита считала space, tab, newline, end-of-file, и разбила поток на аргументы. Пробелы, символы табуляции и символы новой строки могут быть встроены в аргументы с использованием одиночных (') или двойных (") кавычек или обратных косых черт ('\'), знак подстановки команды (`) воспринимается как и все. Одинарные кавычки экранируют все не одинарные кавычки, исключая новые строки, вплоть до совпадения одинарная кавычка. Двойные кавычки экранируют все символы без двойных кавычек, за исключением новых строк, вплоть до совпадающей двойной кавычки.
Любой одиночный символ, включая символы перевода строки, может быть экранирован обратным слэшем. Пустые строки не учитываются.
Первая строка вывела общее число аргументов, как и предполагалось скриптом (echo -n "{total-$#}"), далее выделен {arg1}, одинарные кавычки убраны, дальше идет символ новой строки, поэтому следующий аргумент {arg2}, дальше пробел, значит еще аргумент {space}, дальше {arg3 space} поскольку сгруппированы двойными кавычками ......ну и т.д
Вообщем можно считать, что есть несколько режимов, зависящих от опций:
Обычный. По умолчанию разделителем аргументов считается любой пробельный символ: пробел, табуляция, вертикальная табуляция или перевод строки. Но как и в командной оболочке можно использовать ("")( '')или \ что бы предотвратить разбиение аргумента.
Обычный, с группировкой. Режим, включающийся параметром -L. Практически идентичен предыдущему, за исключением того, что xargs запоминает, какой аргумент на какой строке находится. Более того, если строка оканчивается пробелом или табуляцией, следующая строка считается продолжением текущей.
По строкам. Включается при использовании опции -I или -0. При этом вся строка считается одним целым аргументом, несмотря на пробелы и табуляции внутри. Для -I концом строки является символ '\n' а для -0 символ '\0'
Несколько правил работы с xargs
Использование: xargs [ПАРАМЕТР] КОМАНДА [НАЧАЛЬНЫЕ-АРГУМЕНТЫ] [ДОП.-АРГУМЕНТЫ (STDIN)]
Выполняет КОМАНДУ с аргументами НАЧАЛЬНЫЕ-АРГУМЕНТЫ и дополнительными аргументами, прочитанными из стандартного ввода.
https://www.gnu.org/software/findutils/manual/xargs-options.html
Статус завершения
Ø Все вызовы программы успешно завершены.
> Ø Возникла ошибка
Просмотр файлов
Просмотр файлов в текущем рабочем каталоге и всех подкаталогов в двух столбцах: $ find . -print | xargs -n 2 echo
Xargs не работает с файлами, в имени которых присутствует пробел. Например найти и удалить файлы с расширением ¨*.txt¨:
$ find ~ -name ¨*.txt¨ | xargs rm -rf
и если имя файла будет из двух слов(нескольких символов) разделенных пробелом, то оно не будет воспринято как единое целое, для решения этой проблемы с командой xargs используется опция printØ (для команды find) и опция -Ø (для команды xargs). В результате заменяется стандартный разделитель на нуль символ.
$ find ~ -name ¨*.txt¨ -print0 | xargs -0 rm -rf
$ ~ > "zxc vbn.qw"
$ ~ find -name "*.qw"
./zxc vbn.qw
$ ~ find -name "*.qw" -print0 | xargs -0 echo
./zxc vbn.qw
$ ~ find -name "*.qw" -print0 | xargs -0 rm
$ ~ find -name "*.qw"
$ ~
https://habrahabr.ru/post/179597/
Во многих случаях команду xargs можно заменить циклом for. Например, команда $ find . -type f -and -iname "*.deb" | xargs -n 1 dpkg -I
Полностью эквивалента циклу: $ for file in `find . -type f -and -iname "*.deb"`; do dpkg -I "$file"; done
Применение к результатам команды find
Класический пример использования xargs это применить к результатам работы команды поиска find
Например в качестве фильтра для работы со списком файлов, полученным в результате выполнения поиска командой find. Обычно команда find выдает список файлов, соответствующий некоторому критерию. Этот список передается к xargs, которая выполняет другие операции, используя список файлов в качестве аргументов, как в следующем примере:
Найдем (первое что придет в голову) в домашнем каталоге файлы с названием "names"
$ ~ find ~ -name 'names'
/home/iarch/AUR/dpkg/src/dpkg-1.16.15/dselect/methods/ftp/names
/home/iarch/AUR/dpkg/src/dpkg-1.16.15/dselect/methods/disk/names
/home/iarch/AUR/dpkg/src/dpkg-1.16.15/dselect/methods/multicd/names
/home/iarch/AUR/dpkg/src/dpkg-1.16.15/dselect/methods/floppy/names
/home/iarch/AUR/dpkg/pkg/dpkg/usr/lib/dpkg/methods/ftp/names
/home/iarch/AUR/dpkg/pkg/dpkg/usr/lib/dpkg/methods/disk/names
/home/iarch/AUR/dpkg/pkg/dpkg/usr/lib/dpkg/methods/multicd/names
/home/iarch/AUR/dpkg/pkg/dpkg/usr/lib/dpkg/methods/floppy/names
$ ~
Отсортируем по 5-му полю (считая разделителем слеш):
$ ~ find ~ -name 'names' | sort -t\/ -k5
/home/iarch/AUR/dpkg/pkg/dpkg/usr/lib/dpkg/methods/disk/names
/home/iarch/AUR/dpkg/pkg/dpkg/usr/lib/dpkg/methods/floppy/names
/home/iarch/AUR/dpkg/pkg/dpkg/usr/lib/dpkg/methods/ftp/names
/home/iarch/AUR/dpkg/pkg/dpkg/usr/lib/dpkg/methods/multicd/names
/home/iarch/AUR/dpkg/src/dpkg-1.16.15/dselect/methods/disk/names
/home/iarch/AUR/dpkg/src/dpkg-1.16.15/dselect/methods/floppy/names
/home/iarch/AUR/dpkg/src/dpkg-1.16.15/dselect/methods/ftp/names
/home/iarch/AUR/dpkg/src/dpkg-1.16.15/dselect/methods/multicd/names
$ ~
Теперь например понадобилось посмотреть первую строку, что бы не делать этого с каждым файлом по отдельности применим команду xargs, что и станет примером "автоматизации":
$ ~ find ~ -name 'names' | sort -t\/ -k5 | xargs head -1
==> /home/iarch/AUR/dpkg/pkg/dpkg/usr/lib/dpkg/methods/disk/names <==
30 cdrom Install from a CD-ROM.
==> /home/iarch/AUR/dpkg/pkg/dpkg/usr/lib/dpkg/methods/floppy/names <==
50 floppy Install from a pile of floppy disks.
==> /home/iarch/AUR/dpkg/pkg/dpkg/usr/lib/dpkg/methods/ftp/names <==
60 ftp Install using ftp.
==> /home/iarch/AUR/dpkg/pkg/dpkg/usr/lib/dpkg/methods/multicd/names <==
31 multi_cd Install from a CD-ROM set.
==> /home/iarch/AUR/dpkg/src/dpkg-1.16.15/dselect/methods/disk/names <==
30 cdrom Install from a CD-ROM.
==> /home/iarch/AUR/dpkg/src/dpkg-1.16.15/dselect/methods/floppy/names <==
50 floppy Install from a pile of floppy disks.
==> /home/iarch/AUR/dpkg/src/dpkg-1.16.15/dselect/methods/ftp/names <==
60 ftp Install using ftp.
==> /home/iarch/AUR/dpkg/src/dpkg-1.16.15/dselect/methods/multicd/names <==
31 multi_cd Install from a CD-ROM set.
$ ~
Еще примеры поиска с использованием -exec и xargs
$ ~ find -name "*.txt" -exec ls {} \;
$ ~ find -name "*.txt" -print0 | xargs -0 ls
Стоит испытать и убедиться, что xargs эффективней: https://danielmiessler.com/linux-xargs-vs-exec
Более сложные операции xargs & find find
Удалить временные файлы, созданные более 7 дней назад:
$ sudo find /tmp -type f -name '*' -mtime +7 -print0 | xargs -0 rm -f
Принудительно остановить процессы, работающие больше 7 дней:
$ sudo find /proc -maxdepth 1 -user "myuser" -type d -mtime +7 -exec basename {} \; | xargs kill -9
-maxdepth
максимальный уровень вложенности для поиска. «-maxdepth 1» ограничивает поиск текущим каталогом.
-exec
Выполняет команду оболочки для каждого найденного файла. Единственным «трюком» является замена фактического имени файла на {} и завершение команды с помощью (;).
find -name "*.txt" -exec ls {} \;
Пример с 'parallel'
$ find -name '*.bak' -print0 | xargs -0 parallel gzip --
В этом примере:
find нашел, что "надо"
xarg считывает имена со своего stdin принимая пробелы за NUL (-printØ | xargs -Ø)
parallel запускает экземпляры команды для каждого ядра "ЦП" и дает каждому экземпляру следующий аргумент имени файла
gzip -- указывает parallel. что он должен быть запущен по любым аргументам следующим за --
find Common Options
-type
Specifies the type of file we're looking for. e.g. text file, directory, link, etc.
-name
Specifies the name of the file. Case Sensitive
-iname
Specifies the name of the file. Case Insensitive
-or
Joins the precedeing and following terms by the boolean OR
-and
Joins the preceding and following terms by the boolean AND
-not
negates the next term. e.g. -not -empty means "is not empty"
-exec
Выполняет команду оболочки для каждого найденного файла. Единственным «трюком» является замена фактического имени файла на {} и завершение команды с помощью (;).
find -name "*.txt" -exec ls {} \;
-empty
The file or directory is empty.
https://linux.die.net/man/1/find
Ну и вообщем "стандартный" шаблон примерно такой (хотя и так понятно):
$ find -iname '*~' | xargs rm
$ find [-find option] ['template'] | xargs [command]
Пример, в котором команда find возвращает список всех файлов, имеющихся в системе, а команда xargs выполняет для них команду file, проверяющую тип каждого файла:
$ ls
итого 24
-rw-r--r-- 1 iarch users 19 июн 12 10:55 eddd
-rw-r--r-- 1 iarch users 0 июн 14 21:47 f1
-rw-r--r-- 1 iarch users 0 июн 14 21:47 f2
-rw-r--r-- 1 iarch users 0 июн 14 21:47 f3
-rw-r--r-- 1 iarch users 0 июн 14 21:47 f4
-rw-r--r-- 1 iarch users 31 июн 13 15:11 input
-rw-r--r-- 1 iarch users 0 июн 14 21:45 myfile1
-rw-r--r-- 1 iarch users 0 июн 14 21:45 myfile2
-rw-r--r-- 1 iarch users 0 июн 14 21:45 myfile3
-rw-r--r-- 1 iarch users 158 май 15 09:29 video.txt
-rw-r--r-- 1 iarch users 177 май 15 00:23 video_1.txt
-rw-r--r-- 1 iarch users 172 май 15 09:51 video_2.txt
-rw-r--r-- 1 iarch users 41 май 15 10:28 video_3.txt
$ find . -type f -print | xargs file
./video_2.txt: ASCII text
./myfile2: empty
./myfile3: empty
./f4: empty
./myfile1: empty
./f1: empty
./eddd: ASCII text
./f3: empty
./video_3.txt: ASCII text
./video_1.txt: UTF-8 Unicode text
./f2: empty
./video.txt: ASCII text
./input: ASCII text
$
Ниже приведен пример, демонстрирующий поиск файлов дампа, имена которых команда echo помешает в файл /tmp/core.log.
$ find / -name core -print | xargs echo > /tmp/core.log
В следующем примере в каталоге /apps/audit выполняется поиск всех файлов, к которым другие пользователи имеют полный доступ. Команда chmod удаляет для них разрешение на запись:
$ find /apps/audit -perm -7 -print | xargs chmod o-w
Пример, в котором команда grep ищет файлы, содержащие слово "device":
$ find / -type f -print | xargs grep "device"
Резюмируя примеры применения find можно сказать следующее:
Команда find представляет собой прекрасный инструмент поиска различных файлов по самым разнообразным критериям.
Благодаря опции -exec (exec), а также команде xargs найденные файлы могут быть обработаны практически любой системной командой.
Передача списка с разделяющими пробелами
Xargs использует значение переменной окружения $PATH для поиска команды (которая может быть файлом shell'а). Если команда опущена, используется /bin/echo
Ниже иллюстрируется пример, когда команда опущена, используется echo (каждый раз после ENTER - конец строки, пробел), в результате после Ctr+D, xargs ставит все элементы (строки) на одну строку, разделяя их пробелами:
$ ~ xargs
as
ad
af
ag
<Ctr+D>
as ad af ag
$ ~
Использование инструмента xargs для фильтрации текста в одну строку:
$ ~ ls -l | xargs
итого 15848 -rw-r--r-- 1 iarch users 0 апр 24 11:31 3 drwxr-xr-x 5 iarch root 4096 дек 2 2014 AUR/ drwxr-xr-x 3 iarch root 4096 ноя 11 2014 DEB/ drwxr-xr-x 5 iarch root 4096 фев 28 12:54 Desktop/ drwx------ 2 iarch users 4096 фев 26 20:56 Downloads/ -rw------- 1 iarch users 242620 окт 18 2015 LogAnalyser.png .........
$ ~
Переименование файлов
С помощью xargs можно осуществлять массовое переименование файлов. Представим себе, что у нас есть группа файлов с расширением *.txt, и нам нужно заменить это расширение на *.xxx. Это можно сделать при помощи xargs и потокового текстового редактора sed:
$ find . -type f | sed -e "p;s/.txt/.xxx/" | xargs -n2 -p mv (-p Спрашивать перед выполнением команд)
$ ls
итого 16
-rw-r--r-- 1 iarch users 158 май 15 09:29 video.txt
-rw-r--r-- 1 iarch users 177 май 15 00:23 video_1.txt
-rw-r--r-- 1 iarch users 172 май 15 09:51 video_2.txt
-rw-r--r-- 1 iarch users 41 май 15 10:28 video_3.txt
$ find . -type f | sed -e "p;s/.txt/.xxx/" | xargs -n2 -p mv
mv ./video_2.txt ./video_2.xxx ?...y
mv ./video_3.txt ./video_3.xxx ?...y
mv ./video_1.txt ./video_1.xxx ?...y
mv ./video.txt ./video.xxx ?...y
$ ls
итого 16
-rw-r--r-- 1 iarch users 158 май 15 09:29 video.xxx
-rw-r--r-- 1 iarch users 177 май 15 00:23 video_1.xxx
-rw-r--r-- 1 iarch users 172 май 15 09:51 video_2.xxx
-rw-r--r-- 1 iarch users 41 май 15 10:28 video_3.xxx
$ find . -type f | sed -e "p;s/.xxx/.txt/" | xargs -n2 mv
$ ls
итого 16
-rw-r--r-- 1 iarch users 158 май 15 09:29 video.txt
-rw-r--r-- 1 iarch users 177 май 15 00:23 video_1.txt
-rw-r--r-- 1 iarch users 172 май 15 09:51 video_2.txt
-rw-r--r-- 1 iarch users 41 май 15 10:28 video_3.txt
$
Сжатие файлов
Сжать все файлы в текущей директории с помощью gzip можно, введя следующую команду:
$ ls
итого 16
-rw-r--r-- 1 iarch users 158 май 15 09:29 video.txt
-rw-r--r-- 1 iarch users 177 май 15 00:23 video_1.txt
-rw-r--r-- 1 iarch users 172 май 15 09:51 video_2.txt
-rw-r--r-- 1 iarch users 41 май 15 10:28 video_3.txt
$ find -name "*" | xargs -l gzip
gzip: . is a directory -- ignored
$ ls
итого 16
-rw-r--r-- 1 iarch users 158 май 15 09:29 video.txt.gz
-rw-r--r-- 1 iarch users 170 май 15 00:23 video_1.txt.gz
-rw-r--r-- 1 iarch users 171 май 15 09:51 video_2.txt.gz
-rw-r--r-- 1 iarch users 73 май 15 10:28 video_3.txt.gz
$ find -name "*" | xargs -l gunzip
gzip: . is a directory -- ignored
$ ls
итого 16
-rw-r--r-- 1 iarch users 158 май 15 09:29 video.txt
-rw-r--r-- 1 iarch users 177 май 15 00:23 video_1.txt
-rw-r--r-- 1 iarch users 172 май 15 09:51 video_2.txt
-rw-r--r-- 1 iarch users 41 май 15 10:28 video_3.txt
$
Или так используя du
$ du -a | xargs -l gzip
gzip: 4: No such file or directory
gzip: 4: No such file or directory
gzip: 4: No such file or directory
gzip: 4: No such file or directory
gzip: 20: No such file or directory
gzip: . is a directory -- ignored
$ ls
итого 16
-rw-r--r-- 1 iarch users 158 май 15 09:29 video.txt.gz
-rw-r--r-- 1 iarch users 170 май 15 00:23 video_1.txt.gz
-rw-r--r-- 1 iarch users 171 май 15 09:51 video_2.txt.gz
-rw-r--r-- 1 iarch users 73 май 15 10:28 video_3.txt.gz
$
Пользоваться ls не стоит, поскольку xarg в локали UTF-8 выдаст ошибку:
$ ls | xargs -l gzip
gzip: итого: No such file or directory
gzip: 16: No such file or directory
gzip: invalid option -- 'w'
..................................................
Еще пример: сжатие с помощью tar всех файлов с расширением *.pl:
$ find . -name "*.pl" | xargs tar -zcf pl.tar.gz
Поиск всех изображений jpg в системе и их архивирование
$ find / -name *.jpg -type f -print | xargs tar -cvzf images.tar.gz
Использование cmp
Использование cmp для определения совпадения файлов в каталоге old_data с файлами в каталоге new_data:
$ ls old_data | xargs -i cmp old_data/{} new_data/{}
С помощью xargs можно также добавлять к дополнительные элементы к именам файлов (например, дату):
$ ls | xargs -I FILE mv {} <...>{}
$ find . -type f | xargs -i mv '{}' '{}'mp3
$ find . -type f -exec mv '{}' '{}'.mp3 \;
Блок кода (фигурные скобки) Известен так же как "вложенный блок", эта конструкция, фактически, создает анонимную функцию.
Фигурные скобки {} в этом примере означают «текущий аргумент» (т.е. текущее имя файла), работает как и в find: если содержит {}, то find подставляет полное имя найденного файла вместо "{}".
#!/bin/bash
while [ -e "$1" ]
do
NEW=`date -r "$1" +%Y-%m-%d_%Hh%M`
echo "$1 -> "$NEW"_"$1
# mv "$1" $NEW"_$1"
shift
done
Скрипт, добавляющий в начало имен файлов, перечисленных в комадной строке дату и время. Нужно раскомментировать mv.
Изменение прав для папок и файлов
С помощью xargs можно также ускорить процесс смены прав на файлы и папки для определенного пользователя или группы. Предположим, нам нужно найти все папки пользователя root и заменить их владельца на temp. Эта операция осуществляется при помощи команды:
$ find . -group root -print | xargs chown temp
Чтобы найти все папки группы root и заменить группу на temp, используется команда:
$ find . -group root -print | xargs chgrp temp
Xargs и сut
Xargs довольно часто используется в сочетании с командой cut, позволяющей вырезать строки из текстовых файлов. Рассмотрим некоторые практические примеры. С помощью приведённой ниже команды на консоль будет выведен список всех пользователей системы:
$ cut -d: -f1 < /etc/passwd | sort | xargs echo
А команда вида
file * | grep ASCII | cut -d":" -f1 | xargs -p vim
будет последовательно открывать файлы для редактирования в vim. Обратим внимание на опцию -p. Благодаря ей команда будет выполняться в интерактивном режиме: перед открытием каждого файла будет запрашиваться подтверждение (y/n). В заключение приведём ещё один сложный и интересный пример — рекурсивный поиск файлов самого большого размера в некоторой директории:
$ find . -type f -printf '%20s %p\n' | sort -n | cut -b22- | tr '\n' '\000' | xargs -0 ls -laSr
Параллельный запуск процессов
Xargs часто используется для параллельного запуска нескольких процессов. Вот так, например, можно одновременно cжать несколько директорий в tar.gz:
$ echo dir1 dir2 dir3 | xargs -P 3 -I NAME tar czf NAME.tar.gz NAME
В приведенном примере используется ключ -P. Он указывает максимальное количество процессов, которые будут выполняться одновременно. Предположим, что у нас на входе имеется 10 аргументов. Если мы введём команду xargs с ключoм -P 3, то будет запущено 3 экземпляра команды, следующей после xargs, с каждым из этих аргументов.
С помощью xargs можно также параллельно загружать из Интернета множество файлов:
$ wget -nv <ссылка> | egrep -o "http://[^[:space:]]*.jpg" | xargs -P 10 -n 1 wget -nv
В приведенном примере с указанного адреса будут скачаны все графические файлы с расширением jpg; ключ -P указывает, что требуется скачивать по 10 файлов одновременно.
Запустить в 5 потоков
$ cat links.txt | xargs -P 5 wget {}
Загрузука всех url из файла url-list.txt
$ cat url-list.txt | xargs wget –c
$ cd /etc
$ ls -l | awk '{if (NR % 3 == 0) print "#####################"; print}' | nl -b p'#'
total 1304
-rw-r--r-- 1 root root 3040 May 25 2023 adduser.conf
1 #####################
-rw-r--r-- 1 root root 46 Sep 26 20:11 adjtime
-rw-r--r-- 1 root root 185 Sep 26 21:13 aliases
drwxr-xr-x 3 root root 4096 Oct 1 14:10 alsa
2 #####################
drwxr-xr-x 2 root root 12288 Oct 29 15:18 alternatives
-rw-r--r-- 1 root root 401 Jan 11 2023 anacrontab
drwxr-xr-x 3 root root 4096 Oct 2 21:47 apache2
3 #####################
drwxr-xr-x 3 root root 4096 Oct 1 14:10 apparmor
drwxr-xr-x 8 root root 4096 Dec 9 14:59 apparmor.d
drwxr-xr-x 8 root root 4096 Nov 19 13:33 apt
4 #####################
drwxr-xr-x 3 root root 4096 Oct 1 14:10 avahi
-rw-r--r-- 1 root root 2195 Oct 12 16:22 bash.bashrc
-rw-r--r-- 1 root root 45 Jan 25 2020 bash_completion
5 #####################
drwxr-xr-x 2 root root 4096 Oct 1 14:10 bash_completion.d
-rw-r--r-- 1 root root 367 Sep 22 2022 bindresvport.blacklist
drwxr-xr-x 2 root root 4096 Oct 1 14:10 binfmt.d
6 #####################
drwxr-xr-x 3 root root 4096 Oct 1 14:10 ca-certificates
-rw-r--r-- 1 root root 5989 Jun 11 2023 ca-certificates.conf
-rw-r--r-- 1 root root 119 Jan 11 2022 catdocrc
7 #####################
drwxr-s--- 2 root dip 4096 Oct 1 14:10 chatscripts
drwxr-xr-x 2 root root 4096 Nov 30 16:13 chromium
drwxr-xr-x 2 root root 4096 Nov 30 16:13 chromium.d
8 #####################
drwxr-xr-x 2 root root 4096 Oct 1 14:10 conky
drwxr-xr-x 2 root root 4096 Oct 1 14:10 console-setup
-rw-r--r-- 1 root root 6543 Jun 18 2022 cowpoke.conf
9 #####################
drwxr-xr-x 2 root root 4096 Oct 13 20:49 cracklib
drwxr-xr-x 2 root root 4096 Oct 1 14:10 cron.d
drwxr-xr-x 2 root root 4096 Nov 30 16:12 cron.daily
10 #####################
drwxr-xr-x 2 root root 4096 Oct 1 14:10 cron.hourly
drwxr-xr-x 2 root root 4096 Oct 1 14:10 cron.monthly
-rw-r--r-- 1 root root 1042 Mar 2 2023 crontab
11 #####################
drwxr-xr-x 2 root root 4096 Oct 1 14:10 cron.weekly
drwxr-xr-x 2 root root 4096 Oct 1 14:10 cron.yearly
-rw-r--r-- 1 root root 54 Jun 11 2023 crypttab
12 #####################
drwxr-xr-x 5 root lp 4096 Dec 18 13:39 cups
drwxr-xr-x 2 root root 4096 Oct 1 14:10 cupshelpers
drwxr-xr-x 4 root root 4096 Oct 1 14:10 dbus-1
13 #####################
.....и т.д