103.7 Урок 2
Сертифікат: |
LPIC-1 |
---|---|
Версія: |
5.0 |
Розділ: |
103 GNU та команди Unix |
Тема: |
103.7 Пошук текстових файлів за допомогою регулярних виразів |
Урок: |
2 з 2 |
Вступ
Потокова передача даних через конвеєр команд дозволяє застосовувати складені фільтри на основі регулярних виразів. Регулярні вирази є важливою технікою, яка використовується не лише в системному адмініструванні, а й у інтелектуальному аналізі даних (data mining) та в пов’язаних областях. Дві команди спеціально підходять для маніпулювання файлами та текстовими даними за допомогою регулярних виразів: grep
і sed
. grep
- це шукач шаблонів, а sed
- це редактор потоків. Вони корисні самі по собі, але саме при спільній роботі з іншими процесами вони проявляються найбільше.
Пошук за шаблонами: grep
Одним із найпоширеніших застосувань grep
є полегшення перевірки довгих файлів, використовуючи регулярний вираз як фільтр, що застосовується до кожного рядка. Його можна використовувати для відображення лише рядків, які починаються з певного терміна. Наприклад, grep
можна використовувати для дослідження файлу конфігурації модулів ядра, перераховуючи лише рядки параметрів:
$ grep '^options' /etc/modprobe.d/alsa-base.conf options snd-pcsp index=-2 options snd-usb-audio index=-2 options bt87x index=-2 options cx88_alsa index=-2 options snd-atiixp-modem index=-2 options snd-intel8x0m index=-2 options snd-via82xx-modem index=-2
Символ |
можна використовувати для перенаправлення виведення команди безпосередньо на вхід grep
. У наступному прикладі використовується вираз у дужках, щоб вибрати рядки з виведення fdisk -l
, починаючи з Disk /dev/sda
або Disk /dev/sdb
:
# fdisk -l | grep '^Disk /dev/sd[ab]' Disk /dev/sda: 320.1 GB, 320072933376 bytes, 625142448 sectors Disk /dev/sdb: 7998 MB, 7998537728 bytes, 15622144 sectors
Просто вибірка рядків зі збігами може не підходити для конкретного завдання, що вимагає налаштувань поведінки grep
за допомогою його параметрів. Наприклад, параметр -c
або --count
повідомляє grep
, щоб показати, скільки рядків мають збіги:
# fdisk -l | grep '^Disk /dev/sd[ab]' -c 2
Параметр може бути розміщений до або після регулярного виразу. Інші важливі параметри grep
:
-c
або--count
-
Замість відображення результатів пошуку відображає лише загальну кількість випадків, коли збіг зустрічається в будь-якому заданому файлі.
-i
або--ignore-case
-
Вмикає пошук без урахування регістру.
-f FILE
or--file=FILE
-
Зазначає файл, що містить регулярний вираз, який потрібно використовувати.
-n
або--line-number
-
Показує номер рядка.
-v
або--invert-match
-
Вибирає усі рядки, крім тих, що містять збіги.
-H
або--with-filename
-
Друкує також ім’я файлу, що містить рядок.
-z
або--null-data
-
Замість того, щоб
grep
розглядав вхідні та вихідні потоки даних як окремі рядки (використовуючи newline за замовчуванням), замість цього буде сприймати введення або виведення як послідовність рядків. При поєднанні виведення командиfind
за допомогою її параметра-print0
з командоюgrep
, параметр-z
або--null-data
слід використовувати для обробки потоку таким же чином.
Незважаючи на те, що параметр -H
активований за замовчуванням, коли в якості вхідних даних вказано кілька шляхів до файлів, параметр -H
не активується для окремих файлів. Це може бути критичним у особливих ситуаціях, наприклад, коли grep
викликається безпосередньо за допомогою find
, наприклад:
$ find /usr/share/doc -type f -exec grep -i '3d modeling' "{}" \; | cut -c -100 artistic aspects of 3D modeling. Thus this might be the application you are This major approach of 3D modeling has not been supported oce is a C++ 3D modeling library. It can be used to develop CAD/CAM softwares, for instance [FreeCad
У цьому прикладі find
виводить кожен файл з /usr/share/doc
, а потім передає кожен із них до grep
, який, у свою чергу, виконує пошук без урахування регістру для 3d modeling
всередині файлу. Канал cut
призначений лише для обмеження довжини виводу до 100 стовпців. Зауважте, однак, що неможливо дізнатися, з якого файлу прийшли ці рядки. Ця проблема вирішується шляхом додавання -H
до grep
:
$ find /usr/share/doc -type f -exec grep -i -H '3d modeling' "{}" \; | cut -c -100 /usr/share/doc/openscad/README.md:artistic aspects of 3D modeling. Thus this might be the applicatio /usr/share/doc/opencsg/doc/publications.html:This major approach of 3D modeling has not been support
Тепер можна ідентифікувати файли, де було знайдено кожен збіг. Щоб зробити перелік ще більш інформативним, до рядків зі збігами можна додати початкові та кінцеві рядки:
$ find /usr/share/doc -type f -exec grep -i -H -1 '3d modeling' "{}" \; | cut -c -100 /usr/share/doc/openscad/README.md-application Blender), OpenSCAD focuses on the CAD aspects rather t /usr/share/doc/openscad/README.md:artistic aspects of 3D modeling. Thus this might be the applicatio /usr/share/doc/openscad/README.md-looking for when you are planning to create 3D models of machine p /usr/share/doc/opencsg/doc/publications.html-3D graphics library for Constructive Solid Geometry (CS /usr/share/doc/opencsg/doc/publications.html:This major approach of 3D modeling has not been support /usr/share/doc/opencsg/doc/publications.html-by real-time computer graphics until recently.
Параметр -1
вказує grep
включати один рядок перед і один рядок після, коли він знайде рядок зі збігом. Ці додаткові рядки називаються контекстними рядками і позначаються у виведенні знаком мінус після імені файлу. Такий самий результат можна отримати за допомогою -C 1
або --context=1
і може бути зазначена інша кількість контекстних рядків.
Є дві додаткові програми для grep: egrep
і fgrep
. Програма egrep
еквівалентна команді grep -E
, яка має додаткові функції, крім основних регулярних виразів. Наприклад, з egrep
можна використовувати розширені функції регулярних виразів, на кшалт розгалуження:
$ find /usr/share/doc -type f -exec egrep -i -H -1 '3d (modeling|printing)' "{}" \; | cut -c -100 /usr/share/doc/openscad/README.md-application Blender), OpenSCAD focuses on the CAD aspects rather t /usr/share/doc/openscad/README.md:artistic aspects of 3D modeling. Thus this might be the applicatio /usr/share/doc/openscad/README.md-looking for when you are planning to create 3D models of machine p /usr/share/doc/openscad/RELEASE_NOTES.md-* Support for using 3D-Mouse / Joystick / Gamepad input dev /usr/share/doc/openscad/RELEASE_NOTES.md:* 3D Printing support: Purchase from a print service partne /usr/share/doc/openscad/RELEASE_NOTES.md-* New export file formats: SVG, 3MF, AMF /usr/share/doc/opencsg/doc/publications.html-3D graphics library for Constructive Solid Geometry (CS /usr/share/doc/opencsg/doc/publications.html:This major approach of 3D modeling has not been support /usr/share/doc/opencsg/doc/publications.html-by real-time computer graphics until recently.
У цьому прикладі виразу буде відповідати 3D modeling
або 3D printing
, без урахування регістру. Щоб відобразити лише частини текстового потоку, які відповідають виразу, використаному egrep
, використовуйте параметр -o
.
Програма fgrep
еквівалентна grep -F
, тобто вона не аналізує регулярні вирази. Це корисно під час простого пошуку, коли метою є відповідність літеральному виразу. Тому спеціальні символи, такі як знак долара та крапка, сприйматимуться буквально, а не як значення в регулярному виразі.
Редактор потоку: sed
Метою програми sed
є зміна текстових даних неінтерактивним способом. Це означає, що все редагування здійснюється за попередньо визначеними інструкціями, а не шляхом довільного введення безпосередньо тексту, що відображається на екрані. У сучасній термінології sed
можна розуміти як синтаксичний аналізатор шаблонів: за умови введення тексту він розміщує користувацький вміст у попередньо визначених позиціях або коли знаходить відповідність регулярному виразу.
Sed (Stream Editor), як випливає з назви, добре підходить для потокової передачі тексту через конвеєри. Його основним синтаксисом є sed -f SCRIPT
, коли інструкції редагування зберігаються у файлі SCRIPT
або sed -e COMMANDS
для виконання COMMANDS
безпосередньо з командного рядка. Якщо -f
та -e
відсутні, sed
використовує перший параметр як файл сценарію. Також можна використовувати файл як вхід, просто вказавши його шлях як аргумент до sed
.
Інструкції sed
складаються з одного символа, якому, можливо, передує адреса або за яким слідують один або кілька параметрів, і застосовуються до кожного рядка за раз. Адреси можуть числовим рядком, регулярним виразом або діапазоном рядків. Наприклад, перший рядок текстового потоку можна видалити за допомогою 1d
, де 1
визначає рядок, до якого буде застосована команда видалення d
. Щоб уточнити використання sed
, візьміть виведення команди factor `seq 12`
, яка повертає прості множники для чисел від 1 до 12:
$ factor `seq 12` 1: 2: 2 3: 3 4: 2 2 5: 5 6: 2 3 7: 7 8: 2 2 2 9: 3 3 10: 2 5 11: 11 12: 2 2 3
Видалення першого рядка за допомогою sed
виконується за допомогою 1d
:
$ factor `seq 12` | sed 1d 2: 2 3: 3 4: 2 2 5: 5 6: 2 3 7: 7 8: 2 2 2 9: 3 3 10: 2 5 11: 11 12: 2 2 3
Діапазон рядків можна вказати розділювальною комою:
$ factor `seq 12` | sed 1,7d 8: 2 2 2 9: 3 3 10: 2 5 11: 11 12: 2 2 3
В одному виконанні можна використовувати більше ніж одну інструкцію, розділені крапкою з комою. У цьому випадку, однак, важливо вкласти їх у дужки, щоб крапка з комою не інтерпретувалася оболонкою:
$ factor `seq 12` | sed "1,7d;11d" 8: 2 2 2 9: 3 3 10: 2 5 12: 2 2 3
У цьому прикладі було виконано дві інструкції видалення, спочатку в рядках від 1 до 7, а потім у рядку 11. Адреса також може бути регулярним виразом, тому інструкція відноситься лише до рядків зі збігом:
$ factor `seq 12` | sed "1d;/:.*2.*/d" 3: 3 5: 5 7: 7 9: 3 3 11: 11
Регулярний вираз :.*2.*
збігається з будь-яким введенням числа 2 у будь-якому місці після двокрапки, викликаючи видалення рядків, що відповідають числам, які мають 2 серед дільників. З sed
все, що розміщується між косими рисками (/
), вважається регулярним виразом, і за замовчуванням підтримуються всі базові регулярні вирази. Наприклад, sed -e "/^#/d" /etc/services
показує вміст файлу /etc/services
без рядків, що починаються з #
(рядки коментарів).
Інструкція видалення d
є лише однією з багатьох інструкцій редагування, наданих sed
. Замість того, щоб видаляти рядок, sed
може замінити його заданим текстом:
$ factor `seq 12` | sed "1d;/:.*2.*/c REMOVED" REMOVED 3: 3 REMOVED 5: 5 REMOVED 7: 7 REMOVED 9: 3 3 REMOVED 11: 11 REMOVED
Інструкція c REMOVED
просто замінює рядок текстом REMOVED
. У нашому прикладі на кожен рядок з підрядком, що відповідає регулярному виразу :.*2.*
, впливає інструкція c REMOVED
. Інструкція a TEXT
копіює текст, позначений TEXT
, на новий рядок після рядка зі збігом. Інструкція r FILE
робить те ж саме, але копіює вміст файлу, зазначеного як FILE
. Інструкція w
виконує дію, протилежну r
, тобто рядок буде додано до вказаного файлу.
На сьогоднішній день найбільш часто використовуваною інструкцією sed
є s/FIND/REPLACE/
, яка використовується для заміни відповідності регулярному виразу FIND
текстом, зазначеним як REPLACE
. Наприклад, інструкція s/hda/sda/
замінює підрядок, що відповідає літералу RE hda
, на sda
. Буде замінено лише перший збіг, знайдений в рядку, якщо після інструкції не буде розміщено прапорець g
, як у s/hda/sda/g
.
Більш реалістичний приклад допоможе проілюструвати особливості sed
. Припустимо, медична клініка хоче надіслати своїм клієнтам текстові повідомлення, нагадуючи їм про заплановані прийоми на наступний день. Типовий сценарій реалізації покладається на професійну службу миттєвих повідомлень, яка надає API для доступу до системи, відповідальної за доставку повідомлень. Ці повідомлення зазвичай надходять з тієї ж системи, що запускає програму, яка контролює зустрічі клієнта, ініційовані певним часом доби чи іншою подією. У цій гіпотетичній ситуації програма могла б створити файл під назвою appointments.csv
, що містить табличні дані з усіма зустрічами на наступний день, а потім використати sed
для відтворення текстових повідомлень із файлу шаблону під назвою template.txt
. Файли CSV є стандартним способом експорту даних із запитів до бази даних, тому зразки призначених зустрічей можна надати таким чином:
$ cat appointments.csv "NAME","TIME","PHONE" "Carol","11am","55557777" "Dave","2pm","33334444"
Перший рядок містить мітки для кожного стовпця, які будуть використовуватися для відповідності тегам у файлі зразка шаблону:
$ cat template.txt Hey <NAME>, don't forget your appointment tomorrow at <TIME>.
Знаки менше <
та більше >
були розміщені навколо міток, щоб допомогти ідентифікувати їх як теги. Наступний сценарій Bash аналізує всі зустрічі в черзі, використовуючи template.txt
як шаблон повідомлення:
#! /bin/bash TEMPLATE=`cat template.txt` TAGS=(`sed -ne '1s/^"//;1s/","/\n/g;1s/"$//p' appointments.csv`) mapfile -t -s 1 ROWS < appointments.csv for (( r = 0; r < ${#ROWS[*]}; r++ )) do MSG=$TEMPLATE VALS=(`sed -e 's/^"//;s/","/\n/g;s/"$//' <<<${ROWS[$r]}`) for (( c = 0; c < ${#TAGS[*]}; c++ )) do MSG=`sed -e "s/<${TAGS[$c]}>/${VALS[$c]}/g" <<<"$MSG"` done echo curl --data message=\"$MSG\" --data phone=\"${VALS[2]}\" https://mysmsprovider/api done
Фактичний виробничий сценарій також оброблятиме автентифікацію, перевірку помилок та ведення журналу, але для початку приклад має базову функціональність. Перші інструкції, які виконує sed
, застосовуються лише до першого рядка — адреса 1
у 1s/^"//;1s/","/\n/g;1s/"$//p
— щоб видалити початкові та кінцеві лапки — 1s/^"//
та 1s/"$//
— і замінити роздільники полів символом нового рядка: 1s/","/\n/ g
. Тільки перший рядок потрібен для завантаження назв стовпців, тому невідповідні рядки будуть виключені параметром -n
, що вимагає розміщення прапора p
після останньої команди sed
для друку відповідного рядка. Потім теги зберігаються у змінній TAGS
як масив Bash. Інша змінна масиву Bash створюється командою mapfile
для зберігання рядків з призначеними зустрічами у змінній масиву ROWS
.
Цикл for
використовується для обробки кожного рядка співпадіння, знайденого в ROWS
. Потім лапки та роздільники у співпадінні - співпадіння знаходиться у змінній ${ROWS[$r]}
, яка використовується як here string, замінюються на sed
, подібно до команд, що використовуються для завантаження тегів. Відокремлені значення для призначених зустрічей потім зберігаються у змінній масиву VALS
, де індекси масиву 0, 1 і 2 відповідають значенням для NAME
, TIME
і PHONE
.
Нарешті, вкладений цикл for проходить через масив TAGS
і замінює кожен тег, знайдений у шаблоні, його відповідним значенням у VALS
. Змінна MSG
містить копію наданого шаблону, оновлену командою заміни s/<${TAGS[$c]}>/${VALS[$c]}/g
під час кожного проходження циклу через TAGS
.
Це призводить до відтворення повідомлення на кшталт: "Hey Carol, don’t forget your appointment tomorrow at 11am."
Відтворене повідомлення потім можна надіслати як параметр через HTTP-запит за допомогою curl
, у вигляді поштового повідомлення або будь-яким іншим подібним методом.
Поєднання grep і sed
Команди grep
і sed
можна використовувати разом, коли потрібні складніші процедури аналізу тексту. Як системний адміністратор, ви можете, наприклад, перевірити всі спроби входу на сервер. Файл /var/log/wtmp
записує всі сеанси входу та виходу, а файл /var/log/btmp
записує невдалі спроби входу. Вони записані у двійковому форматі, який можна прочитати за допомогою команд last
та lastb
відповідно.
Висновок lastb
показує не тільки ім’я користувача, використане під час невдалої спроби входу, але також його IP-адресу:
# lastb -d -a -n 10 --time-format notime user ssh:notty (00:00) 81.161.63.251 nrostagn ssh:notty (00:00) vmd60532.contaboserver.net pi ssh:notty (00:00) 132.red-88-20-39.staticip.rima-tde.net pi ssh:notty (00:00) 132.red-88-20-39.staticip.rima-tde.net pi ssh:notty (00:00) 46.6.11.56 pi ssh:notty (00:00) 46.6.11.56 nps ssh:notty (00:00) vmd60532.contaboserver.net narmadan ssh:notty (00:00) vmd60532.contaboserver.net nominati ssh:notty (00:00) vmd60532.contaboserver.net nominati ssh:notty (00:00) vmd60532.contaboserver.net
Параметр -d
співвідносить IP-адресу відповідному імені хоста. Ім’я хоста може давати підказки про постачальника Інтернет-послуг або послугу хостингу, які використовуються для цих невдалих спроб входу. Параметр -a
розміщує ім’я хоста в останньому стовпці, що полегшує фільтрацію, яку ще потрібно застосувати. Параметр --time-format notime
приховує час, коли відбулася спроба входу. Завершення команди lastb
може зайняти деякий час, якщо було занадто багато невдалих спроб входу, тому вихід був обмежений десятьма записами з опцією -n 10
.
Не всі віддалені IP-адреси мають пов’язане ім’я хоста, тому зворотний DNS до них не застосовується, і їх можна відкинути. Хоча ви можете написати регулярний вираз для відповідності очікуваному формату імені хоста в кінці рядка, ймовірно, простіше написати регулярний вираз, щоб він відповідав літері з алфавіту або одній цифрі в кінці рядка. У наведеному нижче прикладі показано, як команда grep
приймає список зі стандартного введення та видаляє рядки без імен хостів:
# lastb -d -a --time-format notime | grep -v '[0-9]$' | head -n 10 nvidia ssh:notty (00:00) vmd60532.contaboserver.net n_tonson ssh:notty (00:00) vmd60532.contaboserver.net nrostagn ssh:notty (00:00) vmd60532.contaboserver.net pi ssh:notty (00:00) 132.red-88-20-39.staticip.rima-tde.net pi ssh:notty (00:00) 132.red-88-20-39.staticip.rima-tde.net nps ssh:notty (00:00) vmd60532.contaboserver.net narmadan ssh:notty (00:00) vmd60532.contaboserver.net nominati ssh:notty (00:00) vmd60532.contaboserver.net nominati ssh:notty (00:00) vmd60532.contaboserver.net nominati ssh:notty (00:00) vmd60532.contaboserver.net
Опція -v
команди grep
показує лише рядки, які не відповідають заданому регулярному виразу. Регулярний вираз, що відповідає будь-якому рядку, що закінчується числом (тобто [0-9]$
), фіксуватиме лише записи без імені хоста. Тому grep -v '[0-9]$'
показуватиме лише рядки, що закінчуються ім’ям хоста.
Вихідні дані можна відфільтрувати ще більше, зберігаючи лише ім’я домену та видаляючи інші частини з кожного рядка. Команда sed
може зробити це за допомогою команди заміни, щоб замінити весь рядок зворотним посиланням на ім’я домену в ньому:
# lastb -d -a --time-format notime | grep -v '[0-9]$' | sed -e 's/.* \(.*\)$/\1/' | head -n 10 vmd60532.contaboserver.net vmd60532.contaboserver.net vmd60532.contaboserver.net 132.red-88-20-39.staticip.rima-tde.net 132.red-88-20-39.staticip.rima-tde.net vmd60532.contaboserver.net vmd60532.contaboserver.net vmd60532.contaboserver.net vmd60532.contaboserver.net vmd60532.contaboserver.net
Екранована дужка в .* \(.*\)$
наказує sed
запам’ятати цю частину рядка, тобто частину між останнім пробілом і кінцем рядка. У прикладі на цю частину посилається \1
і використовується заміна всього рядка.
Зрозуміло, що більшість віддалених хостів намагаються ввійти більше одного разу, тому одне й те саме доменне ім’я повторюється. Щоб приховати записи, які повторюються, спочатку їх потрібно відсортувати (за допомогою команди sort
), а потім передати команді uniq
:
# lastb -d -a --time-format notime | grep -v '[0-9]$' | sed -e 's/.* \(.*\)$/\1/' | sort | uniq | head -n 10 116-25-254-113-on-nets.com 132.red-88-20-39.staticip.rima-tde.net 145-40-33-205.power-speed.at tor.laquadrature.net tor.momx.site ua-83-226-233-154.bbcust.telenor.se vmd38161.contaboserver.net vmd60532.contaboserver.net vmi488063.contaboserver.net vmi515749.contaboserver.net
Було показано, як можна комбінувати різні команди для отримання бажаного результату. Потім список імен хостів можна використовувати для написання блокуючих правил міжмережного екрана або для вжиття інших заходів для забезпечення безпеки серверу.
Вправи до посібника
-
Команда
last
показує список останніх користувачів, які ввійшли в систему, включно з їх вихідними IP-адресами. Як командуegrep
використати для фільтрації виведення командиlast
, показуючи лише входження адреси IPv4, відкидаючи будь-яку додаткову інформацію у відповідному рядку? -
Яку опцію слід надати
grep
, щоб правильно фільтрувати вихідні дані, згенеровані командоюfind
, яка виконується з параметром-print0
? -
Команда
uptime -s
показує останню дату, коли систему було увімкнено, наприклад,2019-08-05 20:13:22
. Яким буде результат командиuptime -s | sed -e 's/(.*) (.*)/\1/'
? -
Яку опцію слід надати
grep
, щоб він рахував відповідні рядки, а не показував їх?
Дослідницькі вправи
-
Основна структура HTML-файлу починається з елементів
html
,head
таbody
, наприклад:<html> <head> <title>News Site</title> </head> <body> <h1>Headline</h1> <p>Information of interest.</p> </body> </html>
Опишіть, як адреси можна використовувати в
sed
для відображення лише елементаbody
та його вмісту. -
Який вираз
sed
видалить усі теги з HTML-документа, зберігаючи лише основний текст? -
Файли з розширенням
.ovpn
дуже популярні для налаштування VPN-клієнтів, оскільки містять не тільки налаштування, а й вміст ключів і сертифікатів для клієнта. Ці ключі та сертифікати спочатку знаходяться в окремих файлах, тому їх потрібно скопіювати до файлу.ovpn
. Враховуючи такий уривок шаблону.ovpn
:client dev tun remote 192.168.1.155 1194 <ca> ca.crt </ca> <cert> client.crt </cert> <key> client.key </key> <tls-auth> ta.key </tls-auth>
Припускаючи, що файли
ca.crt
,client.crt
,client.key
іta.key
знаходяться в поточному каталозі, як конфігурація шаблону повинна бути змінена за допомогоюsed
, щоб замінити кожне ім’я файлу його вмістом?
Підсумки
Цей урок охоплює дві найважливіші команди Linux, пов’язані з регулярними виразами: grep
і sed
. Скрипти та складені команди покладаються на grep
та sed
для виконання широкого спектру завдань фільтрації та аналізу тексту. Урок розглядає такі питання:
-
Як використовувати
grep
та його варіації, такі якegrep
таfgrep
. -
Як використовувати
sed
та його внутрішні інструкції для маніпулювання текстом. -
Приклади застосунків регулярних виразів із використанням
grep
таsed
.
Відповіді на вправи до посібника
-
Команда
last
показує список останніх користувачів, які ввійшли в систему, включно з їх вихідними IP-адресами. Як командуegrep
використати для фільтрації виведення командиlast
, показуючи лише входження адреси IPv4, відкидаючи будь-яку додаткову інформацію у відповідному рядку?last -i | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
-
Яку опцію слід надати
grep
, щоб правильно фільтрувати вихідні дані, згенеровані командоюfind
, яка виконується з параметром-print0
?Опцію
-z
або--null-data
, як уfind . -print0 | grep -z expression
. -
Команда
uptime -s
показує останню дату, коли систему було увімкнено, наприклад,2019-08-05 20:13:22
. Яким буде результат командиuptime -s | sed -e 's/(.*) (.*)/\1/'
?Виникне помилка. За замовчуванням дужки повинні бути екрановані, щоб використовувати зворотні посилання в
sed
. -
Яку опцію слід надати
grep
, щоб він рахував відповідні рядки, а не показував їх?Опцію
-c
.
Відповіді до дослідницьких вправ
-
Основна структура HTML-файлу починається з елементів
html
,head
таbody
, наприклад:<html> <head> <title>News Site</title> </head> <body> <h1>Headline</h1> <p>Information of interest.</p> </body> </html>
Опишіть, як адреси можна використовувати в
sed
для відображення лише елементаbody
та його вмісту.Щоб відображати лише
body
, адреси мають бути/<body>/,/<\/body>/
, як уsed -n -e '/<body>/,/<\/body>/p ''. Опція `-n
надаєтьсяsed
, тому він не друкує рядки за замовчуванням, тому командаp
у кінці виразуsed
для друку відповідних рядків. -
Який вираз
sed
видалить усі теги з HTML-документа, зберігаючи лише основний текст?Вираз sed
s/<[^>]*>//g
замінить будь-який вміст, укладений у<>
, порожнім рядком. -
Файли з розширенням
.ovpn
дуже популярні для налаштування VPN-клієнтів, оскільки містять не тільки налаштування, а й вміст ключів і сертифікатів для клієнта. Ці ключі та сертифікати спочатку знаходяться в окремих файлах, тому їх потрібно скопіювати до файлу.ovpn
. Враховуючи такий уривок шаблону.ovpn
:client dev tun remote 192.168.1.155 1194 <ca> ca.crt </ca> <cert> client.crt </cert> <key> client.key </key> <tls-auth> ta.key </tls-auth>
Припускаючи, що файли
ca.crt
,client.crt
,client.key
іta.key
знаходяться в поточному каталозі, як конфігурація шаблону повинна бути змінена за допомогоюsed
, щоб замінити кожне ім’я файлу його вмістом?Команда
sed -r -e 's/(^[^.]*)\.(crt|key)$/cat \1.\2/e' < client.template > client.ovpn
замінює будь-який рядок, що закінчується на
crt
або.key
, на вміст файлу, ім’я якого дорівнює рядку. Опція-r
вказуєsed
використовувати розширені регулярні вирази, тоді якe
в кінці виразу вказуєsed
замінити збіги результатом командиcat \1.\2
. Зворотні посилання\1
та\2
відповідають назві файлу та розширенню, знайденим у збігу.