Как использовать Sed в Linux

Фотография двух компьютерных мониторов, на которых показано множество кода.

Sed — это простая программа UNIX, которая не создает и не редактирует файлы. Она только модифицирует данные, которые проходят через ее вход, и выводит измененные данные на выходе. Здесь мы рассмотрим краткий обзор философии UNIX, пройдемся по основам использования sed и покажем примеры, как использовать программу для повседневных задач.

Содержание

  • Основы использования Sed
    1. Выбор и обрезка текстовых потоков
    1. Удаление текста из потока Sed
    1. Добавление нового текста в потоки Sed
    1. Поиск и замена текста в Sed
    1. Копирование текстовых данных в хранилище
    1. Использование меток для создания циклов в Sed
    1. Применение постоянных изменений в Sed

Основы использования Sed

Sed — это программа, которая может читать и модифицировать текстовые потоки данных. Это означает, что, в отличие от обычного текстового редактора, sed не изменяет файлы на вашем компьютере напрямую. Вместо этого он действует больше как «фильтр» для входящих данных и позволяет вам преобразовывать их любым удобным вам образом.

Чтобы начать работать с sed, сначала создайте файл с минимум пятью строками текста внутри. Убедитесь, что между вашими строками есть символ «новой строки»:

printf "hello\nmaketecheasier\nworld\nthis\nis\nwonderful\n" > hello.txt

Примечание: хотя этот гид использует многострочный текстовый файл для демонстрации sed, все подкоманды в программе также будут работать с текстом, который поступает из конвейеров UNIX.

Общая команда для sed выглядит так:

sed [option] '{script}' [text file]

Одна из самых базовых функций в sed — это подкоманда n. Она работает, считывая данные из входа sed и помещая их в «пространство шаблона» вашей программы. Это специальный буфер, который удерживает любые входящие тексты перед тем, как sed начнет с ними манипуляции:

sed n hello.txt

Терминал, показывающий содержимое файла

Еще одной из базовых функций sed является подкоманда p. Она, как и n, считывает данные из входа sed и помещает их в пространство шаблона программы. Однако она также явно выводит их на выход вашего терминала.

Использование подкоманды p может быть запутанным для новичков, так как запуск ее с любым текстовым вводом приводит к тому, что sed выводит свой результат дважды. Это происходит, потому что по умолчанию sed автоматически выводит свое пространство шаблона, независимо от того, присутствует ли p или нет:

sed p hello.txt

Терминал, показывающий вывод подкоманды p без флага -n.

Чтобы отключить это странное поведение, добавьте флаг -n перед запуском ваших подкоманд sed:

sed -n p hello.txt

Терминал, показывающий вывод подкоманды p с включенным флагом -n.

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

1. Выбор и обрезка текстовых потоков

Помимо печати, вы также можете использовать sed для выбора и обрезки текста как из потоков данных, так и из файлов. Самый простой способ сделать это — добавить диапазон значений к подкоманде p.

Следующая команда использует синтаксис диапазона sed, чтобы напечатать третью по пятую строку в вашем файле “hello.txt”:

sed -n '3,5p' hello.txt

Терминал, показывающий способность sed печатать конкретные диапазоны строк.

Вы также можете использовать подкоманду p для печати не смежных строк в вашем тексте. Например, следующая команда печатает первую и четвертую строки в файле “hello.txt”:

sed -n '1p; 4p' hello.txt

2. Удаление текста из потока Sed

Sed также может удалять данные из любого входного текстового потока. Это полезно, если вы хотите удалить несколько строк текста из большого файла или очистить вывод программы, чтобы показать только ту информацию, которая вам нужна.

Для этого используйте подкоманду d вместе с конкретной строкой или диапазоном, которые вы хотите удалить:

sed -n '2d; 5d; p' hello.txt

Терминал, показывающий процесс удаления несмежных строк с помощью sed.

Точно так же, как и с печатью строк текста, подкоманда d работает с многострочными диапазонами. Например, следующая команда удалит первые четыре строки из файла “hello.txt”:

sed -n '1,4d; p' hello.txt

В дополнение к совпадению с конкретными диапазонами строк, вы можете использовать регулярные выражения для поиска текста, который вы хотите удалить. Это заставит sed искать любые строки, содержащие слово «world», и удалит их:

sed -n '/world/ d; p' hello.txt

Вы также можете рассматривать регулярные выражения как диапазон для вашего входного файла. Это дает вам больше гибкости в определении ваших выборов в программе:

sed -n '/world/,/wonderful/ d; p' hello.txt

Терминал, показывающий способность sed удалять строки текста на основе шаблона regex.

3. Добавление нового текста в потоки Sed

Помимо удаления текста, sed также может добавлять новый текст в существующие потоки данных. Хотя это не на уровне полноценного текстового редактора, эта функция все равно может быть полезной для разовых правок и основных добавлений текста.

Чтобы добавить новую строку текста, запустите sed с командой a, за которой следует текст, который вы хотите добавить:

sed -n '$a hello' -e 'p' hello.txt

Терминал, показывающий процесс добавления одной строки текста в конец потока sed.

Примечание: флаг -e говорит sed, что строка в кавычках после него является выражением sed. Это позволяет вам цеплять несколько выражений вместе, не вызывая sed несколько раз.

Также возможно включить целые файлы в поток текста sed. Для этого используйте команду r, за которой следует имя файла, который вы хотите добавить:

sed -n '$r welcome.txt' -e 'p' hello.txt

Терминал, показывающий процесс добавления целого файла в конец потока sed.

4. Поиск и замена текста в Sed

Одна из самых мощных функций sed — это его способность находить и заменять текст из текстового потока. В отличие от добавления и удаления текста, это позволяет вам динамически редактировать данные по мере их прохождения через конвейеры UNIX, что делает его гораздо более гибким по сравнению с обычным текстовым редактором.

Начните с тестовой печати вашего текстового входа без каких-либо модификаций от sed:

sed -n 'p' hello.txt

Терминал, печатающий содержимое файла

Замените подкоманду p на s, а затем добавьте три косых черты (/) после нее:

sed -n 's///' -e 'p' hello.txt

Вставьте структурное регулярное выражение строки символов, которые вы хотите сопоставить, между первой и второй косыми чертами. Например, я могу вставить следующее значение, чтобы искать слова, которые начинаются с «wo» в моей входной строке:

sed -n 's/wo*.//' -e 'p' hello.txt

Поместите курсор текста между второй и третьей косыми чертами, а затем укажите текст, который вы хотите использовать для замены ваших совпадений. В отличие от предыдущего столбца, этот раздел не использует структурные регулярные выражения:

sed -n 's/wo.*/website/' -e 'p' hello.txt

По умолчанию sed заменяет только первую строку, которую он совпадает на любой конкретной строке. Это может стать проблемой, если вы хотите заменить каждое вхождение слова в своем текстовом потоке. Чтобы исправить это, добавьте опцию g после третьей косой черты вашего выражения:

sed -n 's/wo.*/website/g' -e 'p' hello.txt

Терминал, показывающий подкоманду замены в sed.

5. Копирование текстовых данных в хранилище

Sed использует два буфера для хранения текстовых данных: пространство шаблона и хранилище. Первое служит временным местом для вашего текста, пока он проходит через выражения sed. Между тем, второе действует как буфер обмена, где вы можете хранить произвольные текстовые данные.

Одним из преимуществ этого подхода является то, что он позволяет вам «сохранять» определенные выводы, не полагаясь на внешние программы. Это может быть полезно, если вы планируете использовать sed для обработки многошаговых манипуляций с текстом.

Чтобы начать использовать хранилище, сначала убедитесь, что у вас есть файл с как минимум несколькими строками текста внутри него:

sed -n 'p' hello.txt

Замените подкоманду p на h, а затем предоставьте либо номер строки, либо значение regex, которое sed будет сопоставлять в вашем файле. Это скажет sed взять эту специфическую строку текста и скопировать ее в свое хранилище:

sed -n '3h' hello.txt

Примечание: данные внутри хранилища не сохраняются между различными командами sed.

Вы также можете использовать подкоманду H, чтобы хранить несколько строк текста внутри вашего хранилища. Например, следующая команда хранит третью и четвертую строки моего текстового файла и выводит их обратно в терминал:

sed -n '3,4H; $ {x; p}' hello.txt

Терминал, показывающий процесс хранения нескольких строк текста в «хранилище» sed.

6. Использование меток для создания циклов в Sed

Хотя sed не является полноценным языком программирования, все же возможно создать циклы внутри программы. Это полезно, если вам нужно выражение sed, которое должно постоянно работать над определенной частью входного текста.

Чтобы создать цикл в sed, вам нужно сначала задать метку для вашего выражения sed. Для этого используйте подкоманду : и укажите метку, которую вы хотите использовать для вашего выражения.

sed -e ':x' hello.txt

Укажите критерии сопоставления для вашего выражения sed. В моем случае я хочу, чтобы оно доходило до конца каждой строки в моем входном тексте:

sed -e ':x; $' hello.txt

Введите подкоманды sed, которые вы хотите запустить всякий раз, когда sed находит совпадение, а затем заключите их в фигурные скобки. Следующее объединит две смежные строки, заменит символ новой строки на пробел, затем вернется к началу выражения:

sed -e ':x; /$/ {N; s/\n/ /g; bx}' hello.txt

Терминал, показывающий процесс удаления символов новой строки с помощью меток sed в циклах.

Вы даже можете расширить это, чтобы сопоставить почти любые виды входного текста. Например, следующая команда использует расширенные функции regex в sed для удаления HTML-тегов из вашего входного текста:

sed -re ':x; s/<[^>]*>//g; {N; bx}' hello.html

Терминал, показывающий, как sed удаляет HTML-теги в файле с помощью циклов.

7. Применение постоянных изменений в Sed

Как и любой другой инструмент UNIX, sed может использовать перенаправление вывода и конвейеры. Это не только позволяет вам соединять sed с другими программами, но и дает вам возможность сделать ваши изменения постоянными.

Следующая строка кода создает новый файл “welcome.txt” из вывода моей команды sed:

sed -n '2p; 6p' hello.txt > hi.txt

Терминал, показывающий способность sed использовать перенаправление вывода для сохранения его вывода в файлы.

Помимо перенаправления вывода, вы также можете использовать встроенный флаг -i для редактирования вашего текущего файла вместо вывода изменений в консоль вашего терминала. Например, следующая команда удаляет любые символы новой строки из моего текстового файла и сохраняет его:

sed -i -e ':x; $; {N; s/\n/ /g; bx}' hello.txt

Терминал, показывающий флаг -i в sed, который позволяет программе «редактировать на месте», а не просто преобразовывать поток.

Если все это побудило вас заинтересоваться командной строкой Linux, вы можете прочитать нашу раннюю статью, в которой мы говорим о некоторых самых интересных подсказках Bash, которые вы можете использовать сегодня.