Получить часть строки до последнего : (или удалить последний символ в строке) (не используя sed, awk и переменных)

На самом деле это единственный раздел про unix на этом форуме

Модераторы: /dev/random, Модераторы разделов

Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение t.t »

Пишу очередную статью о работе в командной строке. Возникла задача: получить часть строки до последнего двоеточия. Не хотелось сейчас давать sed или awk. И хотелось обойтись чистым конвейером, без циклов и переменных. С удивлением обнаружил, что я не знаю, как решить столь простую задачу средствами bash и простых монофункциональных утилит. Просится grep -o, но единственный подходящий шаблон -- ".*:", который захватит и двоеточие тоже. А простых способов удалить последний символ в строке тоже не нашёл. Пока плюнул и написал sed 's/:[^:]*$//', но вопрос покоя не даёт: неужели действительно никак?
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение t.t »

Пока писал, пришёл в голову один способ:

Shell

grep -o '.*:' | grep -o '.*[^:]'


Но мне не кажется, что это значительно лучше, чем sed.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5404
ОС: Gentoo

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение /dev/random »

Если использовать чистый grep, то это, пожалуй, лучшее, что можно придумать. Если же допустить использование perl-совместимых регекспов, то можно так:

Shell

$ echo a:b:c:d | grep -oP '.*(?=:)' a:b:c $ echo a:b:c:d | pcregrep -o '.*(?=:)' a:b:c



("pcregrep" и "grep -P" - это две разные реализации грепа с perl-совместимыми выражениями. pcregrep входит в libpcre, а опция -P появилась в последних версиях GNU grep)
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение sash-kan »

$ echo ${PATH%%:*}
/usr/local/bin

upd. ах да, требуется конвейер…
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение t.t »

/dev/random писал(а):
22.08.2011 15:18
Если использовать чистый grep, то это, пожалуй, лучшее, что можно придумать. Если же допустить использование perl-совместимых регекспов, то можно так:

Shell

$ echo a:b:c:d | grep -oP '.*(?=:)' a:b:c $ echo a:b:c:d | pcregrep -o '.*(?=:)' a:b:c



("pcregrep" и "grep -P" - это две разные реализации грепа с perl-совместимыми выражениями. pcregrep входит в libpcre, а опция -P появилась в последних версиях GNU grep)
Да, об этом я тоже подумал. Но перловые регекспы я не хочу давать рано ещё сильнее, чем sed или awk. Тем более, что этот конкретный их элемент на мой взгляд ненамного проще для объяснения, чем вышеприведенная команда sed.

Остановился на таком варианте: сначала дать с двумя grep -o, а потом, если останется место, объяснить ещё и вариант с sed как иллюстрацию принципа "для любой задачи существует несколько решений на выбор"; при этом про sed в целом не рассказывать, а только про s/// и конкретный регексп.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение t.t »

Олег, похоже, мы в теге sh баг нашли.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5404
ОС: Gentoo

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение /dev/random »

t.t писал(а):
22.08.2011 15:53
Олег, похоже, мы в теге sh баг нашли.

Тег sh добавлен через админку. IPB не поддерживает для таких тегов "дословного" форматирования, как в code. Смайлы подставляются, ссылки сокращаются, теги заменяются, как в обычном тексте. Чтобы это можно было обойти, я в css'ке сделал так, чтобы у тега code, расположенного в теге sh, убиралось оформление. Т.е. если требуется сделать тег sh дословным, то нужно прямо внутрь него поместить тег code.

Но это для более сложных случаев. В своём сообщении я просто отключил смайлы.
Спасибо сказали:
Аватара пользователя
bormant
Сообщения: 1354

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение bormant »

user

$ echo "1:2:3" | rev | cut -d: -f2- | rev 1:2

Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение t.t »

/dev/random писал(а):
22.08.2011 16:00
t.t писал(а):
22.08.2011 15:53
Олег, похоже, мы в теге sh баг нашли.
Тег sh добавлен через админку. IPB не поддерживает для таких тегов "дословного" форматирования, как в code. Смайлы подставляются, ссылки сокращаются, теги заменяются, как в обычном тексте. Чтобы это можно было обойти, я в css'ке сделал так, чтобы у тега code, расположенного в теге sh, убиралось оформление. Т.е. если требуется сделать тег sh дословным, то нужно прямо внутрь него поместить тег code.

Но это для более сложных случаев. В своём сообщении я просто отключил смайлы.
Забыл. Спасибо за напоминание.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение t.t »

bormant писал(а):
22.08.2011 16:07

user

$ echo "1:2:3" | rev | cut -d: -f2- | rev 1:2

Спасибо, хороший вариант. И была ведь у меня мысль перевернуть строку, а man -k reverse посмотреть забыл.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4823
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение SLEDopit »

А еще можно с помощью tr и head:

Код: Выделить всё

echo 1:2:3:4 | tr ':' '\n' | head -n -1 | tr '\n' ':'
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
Nazyvaemykh
Сообщения: 438
Статус: Подопытный участник

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение Nazyvaemykh »

SLEDopit, зашел запостить это ваше сообщение. (:
Только как его на многострочный ввод распространить…
¡ Страсть к разрушению есть творческая страсть!
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4823
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение SLEDopit »

Nazyvaemykh писал(а):
23.08.2011 08:52
Только как его на многострочный ввод распространить…
А в условии такого нет :P

зы. А вообще как-то кроме циклов типа while с переменными, которые ну никак не годятся по условию, ничего в голову и не приходит пока что.
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение t.t »

SLEDopit писал(а):
23.08.2011 09:36
Nazyvaemykh писал(а):
23.08.2011 08:52
Только как его на многострочный ввод распространить…
А в условии такого нет :P
А зачем мне конвейер тогда? (;

SLEDopit писал(а):
23.08.2011 09:36
зы. А вообще как-то кроме циклов типа while с переменными, которые ну никак не годятся по условию, ничего в голову и не приходит пока что.
С rev хороший вариант. Кстати, именно он в итоге и пошёл в статью. bormant, спасибо Вам большое за хорошую и своевременную подсказку.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение drBatty »

t.t писал(а):
22.08.2011 14:34
Пишу очередную статью о работе в командной строке. Возникла задача: получить часть строки до последнего двоеточия. Не хотелось сейчас давать sed или awk. И хотелось обойтись чистым конвейером, без циклов и переменных. С удивлением обнаружил

...что секс в противогазе на высоте 5000 метров н.у.м. не так приятен. Особенно в гамаке.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение t.t »

drBatty писал(а):
27.08.2011 22:07
t.t писал(а):
22.08.2011 14:34
Пишу очередную статью о работе в командной строке. Возникла задача: получить часть строки до последнего двоеточия. Не хотелось сейчас давать sed или awk. И хотелось обойтись чистым конвейером, без циклов и переменных. С удивлением обнаружил
...что секс в противогазе на высоте 5000 метров н.у.м. не так приятен. Особенно в гамаке.

Держите, пожалуйста, свои эмоции при себе. Эту конструкцию гораздо проще объяснить на пальцах, чем основы регулярных выражений.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение ZyX »

t.t писал(а):
31.08.2011 21:57
drBatty писал(а):
27.08.2011 22:07
t.t писал(а):
22.08.2011 14:34
Пишу очередную статью о работе в командной строке. Возникла задача: получить часть строки до последнего двоеточия. Не хотелось сейчас давать sed или awk. И хотелось обойтись чистым конвейером, без циклов и переменных. С удивлением обнаружил
...что секс в противогазе на высоте 5000 метров н.у.м. не так приятен. Особенно в гамаке.

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

Но основы регулярных выражений гораздо нужнее, чем объяснение этой конструкции. А то получается, что конвеер нужен для решения задачи с высосанными из пальца ограничениями, тогда как существует огромное множество задач, где конвеер реально удобен и без него решение становится сложнее, чем с ним. Почему нельзя для примера давать именно такие задачи?
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение drBatty »

t.t писал(а):
31.08.2011 21:57
Держите, пожалуйста, свои эмоции при себе. Эту конструкцию гораздо проще объяснить на пальцах, чем основы регулярных выражений.

ок. Извиняюсь.
Однако, ИМХО, RE - это более простой и прямой путь.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение t.t »

drBatty писал(а):
01.09.2011 08:29
t.t писал(а):
31.08.2011 21:57
Держите, пожалуйста, свои эмоции при себе. Эту конструкцию гораздо проще объяснить на пальцах, чем основы регулярных выражений.
ок. Извиняюсь.
Однако, ИМХО, RE - это более простой и прямой путь.
Это более прямой путь для того, кто уже знает RE. Для человека, совершенно с ними незнакомого они могут быть излишне сложными на этом этапе.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение t.t »

ZyX писал(а):
31.08.2011 23:44
Но основы регулярных выражений гораздо нужнее, чем объяснение этой конструкции. А то получается, что конвеер нужен для решения задачи с высосанными из пальца ограничениями, тогда как существует огромное множество задач, где конвеер реально удобен и без него решение становится сложнее, чем с ним. Почему нельзя для примера давать именно такие задачи?
Это не задача, а маленькая часть большой задачи. Повторюсь: это решение выглядит сложнее для человека, уже знакомого с регулярными выражениями. Тем же, кто их совсем не знает, понять вариант с sed было бы ощутимо сложнее, чем с rev. А совокупная задача там и так не слишком простая, чтобы усложнять ещё и отдельные её моменты. В одной из следующих статей я планирую рассмотреть не одну комплексную задачу, а две-три более мелких. Вот тогда будет уместно начать рассказывать о регулярных выражениях.

Для автора обучающих статей очень важно уметь смотреть на материал глазами читателя. Если бы я не знал о регулярных выражениях и столкнулся с такой задачей, решение с rev было бы для меня наиболее очевидным.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение drBatty »

не знаешь и не хочешь знать RE? Поставь семерочку, *****.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4823
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение SLEDopit »

t.t писал(а):
01.09.2011 12:42
Если бы я не знал о регулярных выражениях и столкнулся с такой задачей, решение с rev было бы для меня наиболее очевидным.
Боюсь, если бы это действительно было так, вы бы так никогда и не освоили регулярки (:
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
Nazyvaemykh
Сообщения: 438
Статус: Подопытный участник

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение Nazyvaemykh »

а можно ли использовать для такой задачи vi (или подобные редакторы)?
$F:D — перейти на последний символ строки, найти предыдущее двоеточие, удалить до конца строки.
Но вот делать это всё из командной строки я не умею.

Конечно, это и сложнее чем и sed, и awk, зато без регулярных выражений.

t.t, я знаю ваше сдержанное отношение vim, но вот использование vim из командой строки — это довольно интересно. Ведь vi, ex — это тоже стандарты POSIX. А для некоторых задач их использование может оказаться не последним по эффективности и выразительности решением.
¡ Страсть к разрушению есть творческая страсть!
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение t.t »

drBatty писал(а):
01.09.2011 13:57
не знаешь и не хочешь знать RE? Поставь семерочку, *****.
Снова только Ваши эмоции. Я не только не говорил про "не хочешь знать" -- напротив, я сказал явно, что в более подходящем контексте о регулярных выражениях планирую рассказывать.

SLEDopit писал(а):
01.09.2011 14:10
t.t писал(а):
01.09.2011 12:42
Если бы я не знал о регулярных выражениях и столкнулся с такой задачей, решение с rev было бы для меня наиболее очевидным.
Боюсь, если бы это действительно было так, вы бы так никогда и не освоили регулярки (:
Вовсе нет. В каком-то смысле это было действительно так. Я впервые начал использовать регулярки на гораздо более сложных задачах, которые конвейерами из простых утилит если и можно решить, то действительно излишне длинно.

Серьёзно, я не вижу в таком решении никакой противоестественности. Напротив: на мой взгляд, это наиболее естественное применение утилиты rev -- операция, которую можно сделать с "перевёртышем" строки, но не с самой строкой.

Nazyvaemykh писал(а):
01.09.2011 14:36
а можно ли использовать для такой задачи vi (или подобные редакторы)?
$F:D — перейти на последний символ строки, найти предыдущее двоеточие, удалить до конца строки.
Но вот делать это всё из командной строки я не умею.

Конечно, это и сложнее чем и sed, и awk, зато без регулярных выражений.

t.t, я знаю ваше сдержанное отношение vim, но вот использование vim из командой строки — это довольно интересно. Ведь vi, ex — это тоже стандарты POSIX. А для некоторых задач их использование может оказаться не последним по эффективности и выразительности решением.
Тут дело не столько в моём отношении к vim (оно как раз вполне хорошее), сколько в отсутствии опыта с ним. В частности, я совершенно не представляю, можно ли его использовать в конвейерах для обработки каждой полученной строки. В целом я не считаю, что это сложнее, чем sed и awk. Вопрос как раз в том, что для такого использования vim его нужно регулярно использовать и в качестве редактора. А здесь уже, в отличие от sed, awk и тем более узкопрофильных утилит командной строки, есть выбор.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
Nazyvaemykh
Сообщения: 438
Статус: Подопытный участник

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение Nazyvaemykh »

Я не знаю, как вывести текст из vim'а на стандартный вывод… а так было бы довольно забавное решение:

echo -e 'hello:world\nmake:install' | vim -c '1,$normal $F:D' -
¡ Страсть к разрушению есть творческая страсть!
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение sash-kan »

t.t писал(а):
01.09.2011 16:03
В частности, я совершенно не представляю, можно ли его использовать в конвейерах для обработки каждой полученной строки.
можно использовать любой редактор (хоть emacs, хоть ooo-word или как он там называется):
см. man vipe

$ dpkg -S /usr/bin/vipe
moreutils: /usr/bin/vipe
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
Аватара пользователя
Nazyvaemykh
Сообщения: 438
Статус: Подопытный участник

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение Nazyvaemykh »

sash-kan, но тут нельзя передать редактору параметры? команды, которые в нём выполнять?
¡ Страсть к разрушению есть творческая страсть!
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение sash-kan »

Nazyvaemykh писал(а):
01.09.2011 19:07
команды, которые в нём выполнять?
нет· а какой смысл передавать vim-у команды, которые он должен выполнить, в случае использования vim-а как звена в pipe?
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5404
ОС: Gentoo

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение /dev/random »

sash-kan писал(а):
01.09.2011 20:43
нет· а какой смысл передавать vim-у команды, которые он должен выполнить, в случае использования vim-а как звена в pipe?

Он предлагал использовать vim в автоматическом режиме, как sed.

Кстати, мысль: прописать аргументы прямо в $EDITOR.
Спасибо сказали:
Аватара пользователя
Nazyvaemykh
Сообщения: 438
Статус: Подопытный участник

Re: Получить часть строки до последнего : (или удалить последний символ в строке)

Сообщение Nazyvaemykh »

Дык, да хотя бы для решния такой задачи, как рассматриваемая: удалить из строк всё, что после последнего двоеточия (без использования awk и sed).
Такое использование даже предполагается в официальном руководстве в пункте 26.4

/dev/random писал(а):
01.09.2011 20:47
sash-kan писал(а):
01.09.2011 20:43
нет· а какой смысл передавать vim-у команды, которые он должен выполнить, в случае использования vim-а как звена в pipe?

Он предлагал использовать vim в автоматическом режиме, как sed.

Кстати, мысль: прописать аргументы прямо в $EDITOR.

Тогда ужь проще использовать временный файл вместо трубки и обычный vim вместо vipe
¡ Страсть к разрушению есть творческая страсть!
Спасибо сказали: