Вопрос или проблема
Я новичок в 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
— это мощный инструмент, который, обладая знаниями и пониманием, способен существенно ускорить и упростить трудоёмкие процессы.