Получить часть строки до последнего : (или удалить последний символ в строке) (не используя sed, awk и переменных)
Модераторы: /dev/random, Модераторы разделов
-
- Бывший модератор
- Сообщения: 7390
- Статус: думающий о вечном
- ОС: Debian, LMDE
Получить часть строки до последнего : (или удалить последний символ в строке)
Пишу очередную статью о работе в командной строке. Возникла задача: получить часть строки до последнего двоеточия. Не хотелось сейчас давать sed или awk. И хотелось обойтись чистым конвейером, без циклов и переменных. С удивлением обнаружил, что я не знаю, как решить столь простую задачу средствами bash и простых монофункциональных утилит. Просится grep -o, но единственный подходящий шаблон -- ".*:", который захватит и двоеточие тоже. А простых способов удалить последний символ в строке тоже не нашёл. Пока плюнул и написал sed 's/:[^:]*$//', но вопрос покоя не даёт: неужели действительно никак?
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
-
- Бывший модератор
- Сообщения: 7390
- Статус: думающий о вечном
- ОС: Debian, LMDE
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
Пока писал, пришёл в голову один способ:
Но мне не кажется, что это значительно лучше, чем sed.
Shell
grep -o '.*:' | grep -o '.*[^:]'
Но мне не кажется, что это значительно лучше, чем sed.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
-
- Администратор
- Сообщения: 5404
- ОС: Gentoo
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
Если использовать чистый grep, то это, пожалуй, лучшее, что можно придумать. Если же допустить использование perl-совместимых регекспов, то можно так:
("pcregrep" и "grep -P" - это две разные реализации грепа с perl-совместимыми выражениями. pcregrep входит в libpcre, а опция -P появилась в последних версиях GNU grep)
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)
-
- Администратор
- Сообщения: 13939
- Статус: oel ngati kameie
- ОС: GNU
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
$ echo ${PATH%%:*}
/usr/local/bin
upd. ах да, требуется конвейер…
/usr/local/bin
upd. ах да, требуется конвейер…
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
при сбоях форума см.блог
-
- Бывший модератор
- Сообщения: 7390
- Статус: думающий о вечном
- ОС: Debian, LMDE
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
Да, об этом я тоже подумал. Но перловые регекспы я не хочу давать рано ещё сильнее, чем sed или awk. Тем более, что этот конкретный их элемент на мой взгляд ненамного проще для объяснения, чем вышеприведенная команда sed./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)
Остановился на таком варианте: сначала дать с двумя grep -o, а потом, если останется место, объяснить ещё и вариант с sed как иллюстрацию принципа "для любой задачи существует несколько решений на выбор"; при этом про sed в целом не рассказывать, а только про s/// и конкретный регексп.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
-
- Бывший модератор
- Сообщения: 7390
- Статус: думающий о вечном
- ОС: Debian, LMDE
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
Олег, похоже, мы в теге sh баг нашли.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
-
- Администратор
- Сообщения: 5404
- ОС: Gentoo
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
Тег sh добавлен через админку. IPB не поддерживает для таких тегов "дословного" форматирования, как в code. Смайлы подставляются, ссылки сокращаются, теги заменяются, как в обычном тексте. Чтобы это можно было обойти, я в css'ке сделал так, чтобы у тега code, расположенного в теге sh, убиралось оформление. Т.е. если требуется сделать тег sh дословным, то нужно прямо внутрь него поместить тег code.
Но это для более сложных случаев. В своём сообщении я просто отключил смайлы.
-
- Сообщения: 1354
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
user
$ echo "1:2:3" | rev | cut -d: -f2- | rev
1:2
Спасибо сказали:
-
- Бывший модератор
- Сообщения: 7390
- Статус: думающий о вечном
- ОС: Debian, LMDE
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
Забыл. Спасибо за напоминание./dev/random писал(а): ↑22.08.2011 16:00Тег sh добавлен через админку. IPB не поддерживает для таких тегов "дословного" форматирования, как в code. Смайлы подставляются, ссылки сокращаются, теги заменяются, как в обычном тексте. Чтобы это можно было обойти, я в css'ке сделал так, чтобы у тега code, расположенного в теге sh, убиралось оформление. Т.е. если требуется сделать тег sh дословным, то нужно прямо внутрь него поместить тег code.
Но это для более сложных случаев. В своём сообщении я просто отключил смайлы.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
-
- Бывший модератор
- Сообщения: 7390
- Статус: думающий о вечном
- ОС: Debian, LMDE
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
Спасибо, хороший вариант. И была ведь у меня мысль перевернуть строку, а man -k reverse посмотреть забыл.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
-
- Модератор
- Сообщения: 4823
- Статус: фанат консоли (=
- ОС: GNU/Debian, RHEL
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
А еще можно с помощью 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.
The more you believe you don't do mistakes, the more bugs are in your code.
-
- Сообщения: 438
- Статус: Подопытный участник
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
SLEDopit, зашел запостить это ваше сообщение. (:
Только как его на многострочный ввод распространить…
Только как его на многострочный ввод распространить…
¡ Страсть к разрушению есть творческая страсть!
-
- Модератор
- Сообщения: 4823
- Статус: фанат консоли (=
- ОС: GNU/Debian, RHEL
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
А в условии такого нет :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.
The more you believe you don't do mistakes, the more bugs are in your code.
-
- Бывший модератор
- Сообщения: 7390
- Статус: думающий о вечном
- ОС: Debian, LMDE
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
А зачем мне конвейер тогда? (;
С rev хороший вариант. Кстати, именно он в итоге и пошёл в статью. bormant, спасибо Вам большое за хорошую и своевременную подсказку.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
...что секс в противогазе на высоте 5000 метров н.у.м. не так приятен. Особенно в гамаке.
-
- Бывший модератор
- Сообщения: 7390
- Статус: думающий о вечном
- ОС: Debian, LMDE
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
Держите, пожалуйста, свои эмоции при себе. Эту конструкцию гораздо проще объяснить на пальцах, чем основы регулярных выражений.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
-
- Сообщения: 355
- ОС: Gentoo
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
Но основы регулярных выражений гораздо нужнее, чем объяснение этой конструкции. А то получается, что конвеер нужен для решения задачи с высосанными из пальца ограничениями, тогда как существует огромное множество задач, где конвеер реально удобен и без него решение становится сложнее, чем с ним. Почему нельзя для примера давать именно такие задачи?
Спасибо сказали:
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
ок. Извиняюсь.
Однако, ИМХО, RE - это более простой и прямой путь.
-
- Бывший модератор
- Сообщения: 7390
- Статус: думающий о вечном
- ОС: Debian, LMDE
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
Это более прямой путь для того, кто уже знает RE. Для человека, совершенно с ними незнакомого они могут быть излишне сложными на этом этапе.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
-
- Бывший модератор
- Сообщения: 7390
- Статус: думающий о вечном
- ОС: Debian, LMDE
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
Это не задача, а маленькая часть большой задачи. Повторюсь: это решение выглядит сложнее для человека, уже знакомого с регулярными выражениями. Тем же, кто их совсем не знает, понять вариант с sed было бы ощутимо сложнее, чем с rev. А совокупная задача там и так не слишком простая, чтобы усложнять ещё и отдельные её моменты. В одной из следующих статей я планирую рассмотреть не одну комплексную задачу, а две-три более мелких. Вот тогда будет уместно начать рассказывать о регулярных выражениях.ZyX писал(а): ↑31.08.2011 23:44Но основы регулярных выражений гораздо нужнее, чем объяснение этой конструкции. А то получается, что конвеер нужен для решения задачи с высосанными из пальца ограничениями, тогда как существует огромное множество задач, где конвеер реально удобен и без него решение становится сложнее, чем с ним. Почему нельзя для примера давать именно такие задачи?
Для автора обучающих статей очень важно уметь смотреть на материал глазами читателя. Если бы я не знал о регулярных выражениях и столкнулся с такой задачей, решение с rev было бы для меня наиболее очевидным.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
не знаешь и не хочешь знать RE? Поставь семерочку, *****.
-
- Модератор
- Сообщения: 4823
- Статус: фанат консоли (=
- ОС: GNU/Debian, RHEL
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
Боюсь, если бы это действительно было так, вы бы так никогда и не освоили регулярки (:
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.
The more you believe you don't do mistakes, the more bugs are in your code.
-
- Сообщения: 438
- Статус: Подопытный участник
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
а можно ли использовать для такой задачи vi (или подобные редакторы)?
$F:D — перейти на последний символ строки, найти предыдущее двоеточие, удалить до конца строки.
Но вот делать это всё из командной строки я не умею.
Конечно, это и сложнее чем и sed, и awk, зато без регулярных выражений.
t.t, я знаю ваше сдержанное отношение vim, но вот использование vim из командой строки — это довольно интересно. Ведь vi, ex — это тоже стандарты POSIX. А для некоторых задач их использование может оказаться не последним по эффективности и выразительности решением.
$F:D — перейти на последний символ строки, найти предыдущее двоеточие, удалить до конца строки.
Но вот делать это всё из командной строки я не умею.
Конечно, это и сложнее чем и sed, и awk, зато без регулярных выражений.
t.t, я знаю ваше сдержанное отношение vim, но вот использование vim из командой строки — это довольно интересно. Ведь vi, ex — это тоже стандарты POSIX. А для некоторых задач их использование может оказаться не последним по эффективности и выразительности решением.
¡ Страсть к разрушению есть творческая страсть!
-
- Бывший модератор
- Сообщения: 7390
- Статус: думающий о вечном
- ОС: Debian, LMDE
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
Снова только Ваши эмоции. Я не только не говорил про "не хочешь знать" -- напротив, я сказал явно, что в более подходящем контексте о регулярных выражениях планирую рассказывать.
Вовсе нет. В каком-то смысле это было действительно так. Я впервые начал использовать регулярки на гораздо более сложных задачах, которые конвейерами из простых утилит если и можно решить, то действительно излишне длинно.
Серьёзно, я не вижу в таком решении никакой противоестественности. Напротив: на мой взгляд, это наиболее естественное применение утилиты rev -- операция, которую можно сделать с "перевёртышем" строки, но не с самой строкой.
Тут дело не столько в моём отношении к vim (оно как раз вполне хорошее), сколько в отсутствии опыта с ним. В частности, я совершенно не представляю, можно ли его использовать в конвейерах для обработки каждой полученной строки. В целом я не считаю, что это сложнее, чем sed и awk. Вопрос как раз в том, что для такого использования vim его нужно регулярно использовать и в качестве редактора. А здесь уже, в отличие от sed, awk и тем более узкопрофильных утилит командной строки, есть выбор.Nazyvaemykh писал(а): ↑01.09.2011 14:36а можно ли использовать для такой задачи vi (или подобные редакторы)?
$F:D — перейти на последний символ строки, найти предыдущее двоеточие, удалить до конца строки.
Но вот делать это всё из командной строки я не умею.
Конечно, это и сложнее чем и sed, и awk, зато без регулярных выражений.
t.t, я знаю ваше сдержанное отношение vim, но вот использование vim из командой строки — это довольно интересно. Ведь vi, ex — это тоже стандарты POSIX. А для некоторых задач их использование может оказаться не последним по эффективности и выразительности решением.
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
-
- Сообщения: 438
- Статус: Подопытный участник
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
Я не знаю, как вывести текст из vim'а на стандартный вывод… а так было бы довольно забавное решение:
echo -e 'hello:world\nmake:install' | vim -c '1,$normal $F:D' -
echo -e 'hello:world\nmake:install' | vim -c '1,$normal $F:D' -
¡ Страсть к разрушению есть творческая страсть!
-
- Администратор
- Сообщения: 13939
- Статус: oel ngati kameie
- ОС: GNU
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
можно использовать любой редактор (хоть emacs, хоть ooo-word или как он там называется):
см. man vipe
$ dpkg -S /usr/bin/vipe
moreutils: /usr/bin/vipe
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
при сбоях форума см.блог
-
- Сообщения: 438
- Статус: Подопытный участник
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
sash-kan, но тут нельзя передать редактору параметры? команды, которые в нём выполнять?
¡ Страсть к разрушению есть творческая страсть!
-
- Администратор
- Сообщения: 13939
- Статус: oel ngati kameie
- ОС: GNU
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
нет· а какой смысл передавать vim-у команды, которые он должен выполнить, в случае использования vim-а как звена в pipe?
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
при сбоях форума см.блог
-
- Администратор
- Сообщения: 5404
- ОС: Gentoo
-
- Сообщения: 438
- Статус: Подопытный участник
Re: Получить часть строки до последнего : (или удалить последний символ в строке)
Дык, да хотя бы для решния такой задачи, как рассматриваемая: удалить из строк всё, что после последнего двоеточия (без использования awk и sed).
Такое использование даже предполагается в официальном руководстве в пункте 26.4
Тогда ужь проще использовать временный файл вместо трубки и обычный vim вместо vipe
Такое использование даже предполагается в официальном руководстве в пункте 26.4
/dev/random писал(а): ↑01.09.2011 20:47
Он предлагал использовать vim в автоматическом режиме, как sed.
Кстати, мысль: прописать аргументы прямо в $EDITOR.
Тогда ужь проще использовать временный файл вместо трубки и обычный vim вместо vipe
¡ Страсть к разрушению есть творческая страсть!