С помощью терминала: использование регулярных выражений II: замены

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

Еще немного о команде grep

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

Объединение регулярных выражений

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

curl http://artigoo.com/lista-de-frases-comparativas-comicas 2>/dev/null | sed -n 's/.*\(.*\.\)<\/p>/\1/gp' > frases

 Вы попадете в каталог, в котором вы запускаете файл с именем «phrases». Вы можете открыть его, чтобы посмотреть и немного посмеяться. 🙂

Теперь предположим, что мы хотим найти фразы, содержащие ровно 6 слов. Сложность состоит в том, чтобы сформировать регулярное выражение, которое соответствует каждому слову. Слово - это последовательность букв в верхнем или нижнем регистре, которая может выглядеть примерно так: '[a-zA-Z]+', но вы также должны указать, что эти буквы должны быть разделены другими символами, а не буквами, то есть это будет что-то вроде '[a-zA-Z]+[^a-zA-Z]+'. Напомним: «^» в качестве первого символа в скобках указывает на то, что мы хотим сопоставить символы, не входящие в диапазон, а «+» указывает на 1 или более символов.

У нас уже есть регулярное выражение, которое может соответствовать слову. Чтобы соединить его с 6, его придется повторить 6 раз. Для этого мы использовали ключи, но ставить бесполезно '[a-zA-Z]+[^a-zA-Z]+{6}', потому что 6 будет повторять последнюю часть регулярного выражения, и мы хотим повторить все это, поэтому мы должны указать следующее: '([a-zA-Z]+[^a-zA-Z]+){6}'. Скобками мы формируем подвыражение, а скобками повторяем его 6 раз. Теперь вам просто нужно добавить «^» впереди и «$» сзади, чтобы соответствовать всей строке. Команда выглядит следующим образом:

grep -E '^([a-zA-Z]+[^a-zA-Z]+){6}$' frases

И результат как раз то, что мы хотели:

Его поют больше, чем Макарена. Вы более закончены, чем Луис Агиле. У вас меньше культуры, чем у камня. Вы знаете больше языков, чем Чанита Брава. У него больше морщин, чем у Тутана Кхамона. Ты знаешь об уходе за детьми меньше, чем Рэмбо.

Обратите внимание, что мы поместили параметр -E, потому что хотим использовать расширенные регулярные выражения, чтобы «+» работал. Если бы мы использовали базовые, нам пришлось бы избегать скобок и фигурных скобок.

Обратные ссылки или обратные ссылки

Если у вас установлена ​​проверка орфографии, у вас, вероятно, будет список слов в /usr/share/dict/words. Если нет, вы можете установить его в Arch с помощью:

sudo pacman -S words

Или в debian с:

sudo aptitude install dictionaries-common

Если хотите, можете посмотреть в файле, какие слова в нем есть. На самом деле это ссылка на файл Word для языка, на котором находится ваш дистрибутив. Вы можете установить несколько файлов Word одновременно.

Мы собираемся использовать этот файл. Оказывается, нам очень любопытно узнать все существующие семибуквенные палиндромы. Для тех, кто не знает: палиндром - это слово capicúa, то есть его можно читать как слева направо, так и справа налево. Давайте попробуем следующую команду:

grep '^\(.\)\(.\)\(.\).\3\2\1$' /usr/share/dict/words

Выглядит немного странно, правда? Если мы попробуем это сделать, результат будет зависеть от языка вашего дистрибутива и слов в вашем списке, но в моем случае с испанским языком результат будет следующим:

анилин анилиновый прокат

Посмотрим, как работает это регулярное выражение.

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

Здесь три числа ниже идут с косой чертой перед ними. В этом случае важна планка. Он используется для обозначения того, что приведенное ниже число является обратной ссылкой и относится к одной из предыдущих скобок. Например: \ 1 относится к первой скобке, \ 2 - ко второй и так далее.

То есть с введенным нами регулярным выражением мы ищем все слова, которые начинаются с любых четырех букв, а затем имеют букву, которая совпадает с третьей, другая такая же, как вторая, и еще одна. это то же самое, что и первое. Результатом являются палиндромы из семи букв, которые есть в списке слов. Как мы и хотели.

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

Выражения замены: команда sed

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

sed [-r] 's/REGEX/REPL/g' FICHERO

Или также:

COMANDO | sed [-r] 's/REGEX/REPL/g'

Где REGEX будет регулярным выражением поиска, а REPL - заменяющим. Имейте в виду, что эта команда на самом деле ничего не заменяет в указанном нами файле, но она показывает нам результат замены в терминале, поэтому не пугайтесь команд, которые я собираюсь поместить дальше. Ни один из них не собирается изменять какие-либо файлы в вашей системе.

Начнем с простого примера. У всех нас есть различные файлы конфигурации в каталоге / etc, комментарии к которым обычно начинаются с "#". Предположим, мы хотим увидеть один из этих файлов без комментариев. Например, я собираюсь сделать это с помощью fstab. Вы можете попробовать с тем, что хотите.

sed 's/#.*//g' /etc/fstab

Я не собираюсь помещать здесь результат команды, потому что это зависит от того, что у вас есть в вашем fstab, но если вы сравните вывод команды с содержимым файла, вы увидите, что все комментарии исчезли.

В этой команде поисковое выражение - «#.*", То есть" # ", за которым следует любое количество символов, то есть комментарии. И выражение замены, если вы посмотрите на две полосы подряд, вы увидите, что их нет, поэтому оно заменяет комментарии ничем, то есть удаляет их. Проще невозможно.

Теперь поступим наоборот. Предположим, что мы хотим прокомментировать все строки файла. Попробуем вот так:

sed 's/^/# /g' /etc/fstab

Вы увидите, что в выводе команды все строки начинаются с решетки и пробела. Мы сделали следующее: заменили начало строки на «# «. Это также довольно простой пример, в котором заменяемый текст всегда один и тот же, но теперь мы собираемся его немного усложнить.

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

sed 's/\([A-Z]\)/(\1)/g' frases

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

Есть еще один символ, который также можно использовать в выражении замены, это «&», и он заменяется всем текстом, совпадающим с выражением поиска. Примером этого может быть размещение всех фраз в файле в кавычках. Этого можно добиться с помощью этой команды:

sed 's/.*/"&"/g' frases

Работа этой команды очень похожа на предыдущую, только теперь мы заменяем всю строку такой же строкой с кавычками вокруг нее. Поскольку мы используем «&», нет необходимости ставить круглые скобки.

Некоторые полезные команды с регулярными выражениями

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

  • Показать разделы справочной страницы:

man bash | grep '^[A-Z][A-Z ]*$'

Конечно, вы можете изменить команду bash на все, что захотите. А затем из man вы можете перейти непосредственно к интересующему вас разделу, используя, конечно же, регулярное выражение. Вы нажимаете «/», чтобы начать поиск, и пишете «^ALIASES$»Для перехода, например, в раздел НИКНЕЙМЫ. Я думаю, что это первое использование регулярных выражений, которое я начал использовать несколько лет назад. Без подобной уловки пролистать некоторые страницы руководства практически невозможно.

  • Показать имена всех пользователей машины, в том числе специальных:

sed 's/\([^:]*\).*/\1/' /etc/passwd

  • Показывать имена пользователей, но только с оболочкой:

grep -vE '(/false|/nologin)$' /etc/passwd | sed 's/\([^:]*\).*/\1/g'

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

  • Вставьте запятую перед последними тремя цифрами всех чисел в файле чисел:

sed 's/\(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)/\1\2,\3/g' numbers

Он работает только с числами до 6 цифр, но его можно вызвать более одного раза, чтобы поместить разделители в другие группы из трех цифр.

  •  Извлеките все адреса электронной почты из файла:

grep -E '\<[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}\>' FICHERO

  • Отделите день, месяц и год от всех дат, которые появляются в файле:

sed -r 's/([0-9]{2})[/-]([0-9]{2})[/-]([0-9]{4})/Día: \1, Mes: \2, Año: \3/g' FICHERO

  • Узнайте наш локальный IP-адрес:

/sbin/ifconfig | grep 'inet .*broadcast' | sed -r 's/[^0-9]*(([0-9]+\.){3}[0-9]+).*/\1/g'

Это также можно сделать с помощью одной команды sed, но для простоты лучше разделить ее на grep и sed.

Некоторые полезные адреса

Вот несколько адресов, которые могут быть полезны в связи с регулярными выражениями:

  • Библиотека регулярных выражений: Это библиотека регулярных выражений, в которой вы можете искать регулярные выражения, относящиеся к интересующей вас теме. Для поиска веб-адресов, идентификатора или чего-то еще.
  • RegExr: Онлайн-средство проверки регулярных выражений. Он позволяет вводить текст и применять к нему регулярное выражение либо искать, либо заменять. Он дает информацию о регулярном выражении, и у вас есть несколько вариантов изменить его поведение.
  • Тестер регулярных выражений: Это надстройка для Firefox, которая позволяет вам проверять регулярные выражения из браузера.

Заключение

А пока это все. Регулярные выражения сложны, но полезны. Чтобы выучить их, нужно время, но если вы похожи на меня, играть с ними будет весело, и постепенно вы овладеете ими. Это целый мир. Еще многое предстоит сказать о ленивых квантификаторах, регулярных выражениях в стиле PERL, многострочности и т. Д. Кроме того, каждая программа имеет свои характеристики и свои варианты, поэтому лучший совет, который я могу вам дать, - это всегда смотреть документацию по программе, которую вы используете, каждый раз, когда вам нужно написать регулярное выражение в новой программе.

Привет! …ПРИВЕТ! … ПРОСЫПАЙСЯ! … ЧТО ВЫ ВСЕ СПИТЕ? 🙂

Источники

Некоторые идеи и примеры регулярных выражений из этой статьи я почерпнул отсюда:


Содержание статьи соответствует нашим принципам редакционная этика. Чтобы сообщить об ошибке, нажмите здесь.

15 комментариев, оставьте свой

Оставьте свой комментарий

Ваш электронный адрес не будет опубликован. Обязательные для заполнения поля помечены *

*

*

  1. Ответственный за данные: Мигель Анхель Гатон
  2. Назначение данных: контроль спама, управление комментариями.
  3. Легитимация: ваше согласие
  4. Передача данных: данные не будут переданы третьим лицам, кроме как по закону.
  5. Хранение данных: база данных, размещенная в Occentus Networks (ЕС)
  6. Права: в любое время вы можете ограничить, восстановить и удалить свою информацию.

  1.   Elav сказал

    Виртуозно !!!

    1.    гексборг сказал

      Это не так уж и плохо, но спасибо большое. Надеюсь, людям это понравится. 🙂

      1.    Оскар сказал

        Мне это нравится, ха!

        1.    гексборг сказал

          Тогда я, должно быть, сделал что-то правильно. СМЕШНО!! 🙂

          Большое спасибо за ваш комментарий.

          1.    Блэр Паскаль сказал

            Черт возьми, продолжай писать, мужик, так держать.

          2.    гексборг сказал

            @Blaire Pascal: Комментарии, подобные вашему, поощряют это. 🙂 Большое спасибо !!

      2.    Citux сказал

        Мне тоже понравилось ... спасибо 🙂

        1.    гексборг сказал

          Спасибо за комментарий. Надеюсь написать еще несколько. 🙂

  2.   Мэриан сказал

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

    Вы думали о том, чтобы собрать все сообщения о сценариях оболочки? Сортировка в формате pdf станет отличным руководством.

    Поднимает настроение и большое вам спасибо!

    1.    гексборг сказал

      Большое спасибо!! Это неплохая идея. На данный момент их всего два, но об этом я подумаю позже. 🙂

  3.   Киев сказал

    очень хорошая статья, 5+.

    1.    гексборг сказал

      Спасибо. Я рада что тебе нравиться. 🙂

  4.   Себастьян сказал

    Отлично! Мне нужно изменить следующее выражение, и я не знаю, как это сделать:
    192.168.0.138/Server по 192.168.0.111/data
    Проблема заключается в символе «/».
    Я использую команду:
    находить. -name "* .txt" -exec sed -i 's / TEXT1 / TEXT2 / g' {} \;
    Что используется для выполнения такого рода задач без особого труда, но я не могу ...
    Кто-нибудь знает, как мне это делать?
    Hug!
    Seba

    1.    гексборг сказал

      Что вам нужно сделать, так это уйти от персонажа следующим образом:

      находить. -name "* .txt" -exec sed -i 's / \ / Server / \ / data / g' {} \;

      Вы также можете использовать другой разделитель в sed. Это не обязательно должен быть бар. Сед позволяет использовать любого персонажа. Например, это было бы яснее:

      находить. -name "* .txt" -exec sed -i 's | / Server | / data | g' {} \;

      И если вы собираетесь копировать и вставлять команды из этого комментария, будьте осторожны с кавычками, этот wordpress заменяет их типографскими. 🙂

      Привет.

  5.   Себастьян сказал

    Превосходно!!!!
    Давно искал это решение.
    Здесь я оставляю полную команду, которую я использовал

    находить. -name "* .txt" -exec sed -i 's | 192 \ .168 \ .0 \ .238 \ / Server | 192 \ .168 \ .0 \ .111 \ / data | g' {} \;

    Преимущество этой команды в том, что она рекурсивно изменяет все файлы .txt (или желаемое расширение) ... Вы должны быть очень осторожны!
    Но это очень полезно !!!

    Что ж, спасибо за все и тысячу поздравлений всей группе.
    Я их всегда читаю по почте!
    Объятия
    Seba