Сжимать, удалять все после слова.

Вопрос или проблема

Я новичок в sed, у меня есть строка

lightdm --session-child 14 21

два числа могут измениться, и я хочу удалить все
после lightdm

Я пробовал разные способы, но ни один не сработал

sed 's/ --session-child*//'
sed 's/\ --session-child*//'
sed 's/ --session-child*$//'

и другие, но ни один не сработал
в чем ошибка?

* в регулярных выражениях означает “повторять предыдущий символ (или класс символов) произвольно много раз. Так что, --session-child* совпадает с

  • --session-chil
  • --session-child
  • --session-childd
  • --session-childdd
  • --session-childddd
  • Я думаю, вы понимаете, к чему это приводит.

Тем не менее, это не совпадает с --session-child 1, потому что не является d! (и также не является 1, но это уже не имеет значения. Цепочка d прервана.)

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

Таким образом, вам нужно использовать sed 's/ --session-child.*//'

Тем не менее, я склонен выступать за то, чтобы выбирать те вещи, которые вы хотите, вместо того, чтобы стирать те, которые вы не хотите. Я не знаю, что вы изначально имели в виду, но предполагая, что вы хотели сохранить что-либо до первого пробела, я бы написал это так: sed 's/^\([^ ]*\) .*$/\1/'. Это означает: с начала строки (^), начинайте новую группу (включенную в \(\)). Эта группа содержит любой символ, который находится в классе символов (заключенном в []), описанном как ^ , что означает “все, кроме” (^) пробела . Повторяйте это как можно больше раз (0 или более) при первой возможности (первое *).

Если после этого идет пробел, поглощайте этот пробел и все символы до конца строки ($) и заменяйте их на первую (и единственную) совпавшую группу, \1.

На это уходит намного больше усилий для записи. Зачем я это делаю? Потому что написание того, чего вы не хотите, часто является умственным упражнением, включающим предположения, которые не присущи самой проблеме. Например, здесь вы предполагаете, что первый аргумент для чего-либо перед этим — --session-child. Теперь, если это “что-либо” не lightdm, почему бы ему принимать аргумент --session-child? И если это всегда было lightdm, почему бы вообще использовать sed? Вы бы просто вывели lightdm. Таким образом, избегая предположений о “милом маленьком побочном факте”, сосредотачиваясь на действительно важном для меня, я могу избежать будущих ошибок с неожиданными вводными данными.

Ответ или решение

Теория (Theory):

Во многих случаях, работа с текстовыми данными в UNIX-системах требует использования утилиты sed для обработки строк. sed, также известный как Stream Editor, используется для выполнения элементарных текстовых преобразований. Одной из частых задач является задача удаления части строки после определённого слова или символа. В вашем случае вы хотите удалить всё, что идёт после слова "lightdm".

Хотя регулярные выражения (RegEx) и sed кажутся сложными на первый взгляд, они помогают решить данную задачу довольно эффективно. В контексте sed, символы регулярного выражения могут быть использованы для поиска и замены частей строки. Например, комбинация .* в регулярном выражении обозначает "любое количество произвольных символов", начиная с нуля. Это значит, что вы можете с её помощью указать "всё после определённого символа или слова".

Пример (Example):

Рассмотрим ваш начальный пример строки:

lightdm --session-child 14 21

И вашу цель: удалить всё после "lightdm". Пример команды sed, которая решает вашу задачу, выглядит так:

sed 's/lightdm.*/lightdm/'

Это регулярное выражение (lightdm.*) ищет вхождение "lightdm" и всё, что следует за ним — любое количество любых символов (.*). Замена (вторая часть команды) остаётся просто "lightdm". Таким образом, результат применения этого выражения будет:

lightdm

Также стоит рассмотреть иной подход — вместо удаления ненужной части строки, можно сохранить только нужную. Это можно сделать посредством группирования в регулярных выражениях:

sed 's/^\(lightdm\).*/\1/'

Этот вариант достигает аналогичной цели. Здесь выражение \(lightdm\) создает группу, а вторая часть команды обратной подстановкой \1 сохраняет только эту часть, удаляя всё остальное.

Применение (Application):

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

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

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

Оцените материал
Добавить комментарий

Капча загружается...