Вхождение подстроки в строку

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

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

Аватара пользователя
radial
Сообщения: 577
ОС: OpenSUSE

Вхождение подстроки в строку

Сообщение radial »

Подскажите, как проверить наличие подстроки в строке, игнорируя регистр символов?
Элементарный вариант

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

if [ $(echo $string | grep -i $substring >/dev/null) ]; then ...
у меня почему-то элементарно не работает ((
Спасибо сказали:
allez
Сообщения: 2223
Статус: Не очень злой админ :-)
ОС: SuSE, CentOS, FreeBSD, Windows

Re: Вхождение подстроки в строку

Сообщение allez »

Да вроде бы работает...

...

$ STRING="hs8e3hedndi4557"; SUBSTRING="hedn"; echo "$STRING" | grep -iq "$SUBSTRING" && echo "Substring found" || echo "Substring not found" Substring found $ STRING="hs8e3hedndi4557"; SUBSTRING="bla"; echo "$STRING" | grep -iq "$SUBSTRING" && echo "Substring found" || echo "Substring not found" Substring not found


P. S. Если же использовать ваш вариант, то следует воспользоваться командой "test":

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

if [ test $(echo $string | grep -i $substring >/dev/null) ]; then ...

И таки вместо посыла в /dev/null я все же предпочел бы ключ -q команды grep:

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

if [ test $(echo $string | grep -iq $substring) ]; then ...
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: Вхождение подстроки в строку

Сообщение watashiwa_daredeska »

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

if echo "$string" | grep -i "$substring" >/dev/null; then
Спасибо сказали:
Аватара пользователя
radial
Сообщения: 577
ОС: OpenSUSE

Re: Вхождение подстроки в строку

Сообщение radial »

allez, ага. Спасибо, пригодится.
watashiwa_daredeska
это работает! только не понимаю, почему :)
Спасибо сказали:
allez
Сообщения: 2223
Статус: Не очень злой админ :-)
ОС: SuSE, CentOS, FreeBSD, Windows

Re: Вхождение подстроки в строку

Сообщение allez »

Потому что при использовании квадратных скобок в операторе if производится проверка выражения, а не статуса завершения команды. Если ввести в условие проверку на равенство или неравенство, то оно заработает:

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

if [ "$(echo $string | grep -io $substring)" = "$substring" ]; then ...
Спасибо сказали:
Аватара пользователя
radial
Сообщения: 577
ОС: OpenSUSE

Re: Вхождение подстроки в строку

Сообщение radial »

Такой быдлокодер как я просто в экстазе от bash!
С учетом всего вышесказанного навел глянец в скрипте.
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: Вхождение подстроки в строку

Сообщение watashiwa_daredeska »

radial писал(а):
12.06.2010 18:58
только не понимаю, почему
Потому что if проверяет статус завершения команды. Всё, ничего больше. «[» — это не синтаксическая конструкция bash, это команда такая, синоним test (почти, ибо «[» допускает «]» в качестве последнего аргумента, хотя и не UPD: обязательно требует).

Shell

$ which '[' /usr/bin/
Хотя, на самом деле, в bash есть встроенные «test» и «[», которые и используются по умолчанию. Так что, if [ $(echo $string | grep -i $substring >/dev/null) ]; then выполняет и проверяет статус команды [ $(echo $string | grep -i $substring >/dev/null) ]. Конструкция $(command) подставляет вывод command, т.к. в данном случае используется «>/dev/null», на выходе ничего нет. Т.к. эта конструкция не в кавычках, она не порождает даже пустой строки, на этом месте просто нет аргумента, т.е. команда выглядит как [ ], код ее завершения всегда ≠0, т.е. if всегда идет по ветке else, независимо от $string, $substring.
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: Вхождение подстроки в строку

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

allez писал(а):
12.06.2010 17:34
P. S. Если же использовать ваш вариант, то следует воспользоваться командой "test":

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

if [ test ... ]; then ...
Т.е. test test? (:
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
radial
Сообщения: 577
ОС: OpenSUSE

Re: Вхождение подстроки в строку

Сообщение radial »

т.е. в конвейере if echo "$string" | grep -i "$substring" оператор if проверяет статус завершения последней команды (grep в данном случае), и только?
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: Вхождение подстроки в строку

Сообщение watashiwa_daredeska »

radial:
Формально, if проверяет статус завершения «составной» команды (весь пайп), но пайп устроен так, что статусом его завершения является статус завершения последней команды в пайпе. Т.е., короче говоря, да, if проверяет статус завершения grep'а.
Спасибо сказали:
Аватара пользователя
radial
Сообщения: 577
ОС: OpenSUSE

Re: Вхождение подстроки в строку

Сообщение radial »

Ладно, весь скрипт такой:

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

#!/bin/bash
if [ $(expr length $1) -le 2 ]
then exit 1
fi

dfiles="/home/$USER/.local/share/applications/*.desktop /usr/share/applications/*.desktop"

for i in $dfiles
do
    for file in $i
    do
    echo $file
    name="$(awk -F "=" '/Exec/ {print $2}' $file)"
    if echo "$name" | grep -i $1 >/dev/null
    then exec $(echo $name | cut -d ' ' -f1)
    fi
    done
done
exit 0

Я думаю понятно, что он делает. Так будет полностью "по канонам" или можно еще оптимизировать/ исправить?

UPD: скрипт запускает приложения по неполному имени приложения, т.н. "быстрый запуск".
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: Вхождение подстроки в строку

Сообщение watashiwa_daredeska »

radial писал(а):
12.06.2010 22:52

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

dfiles="/home/$USER/.local/share/applications/*.desktop /usr/share/applications/*.desktop"

for i in $dfiles
do
    for file in $i
В $i уже попадают отдельные файлы и второй for не нужен.
Спасибо сказали:
Аватара пользователя
radial
Сообщения: 577
ОС: OpenSUSE

Re: Вхождение подстроки в строку

Сообщение radial »

если я уберу второй for, то прочие действия из второго цикла тоже будут последовательно применяться к каждому файлу *.desktop в выбранной директории?
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: Вхождение подстроки в строку

Сообщение watashiwa_daredeska »

Ну да, естественно, только первый for тогда надо записать как for file in $dfiles или заменить использование $file на $i в теле цикла.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Вхождение подстроки в строку

Сообщение drBatty »

radial писал(а):
12.06.2010 22:52
Я думаю понятно, что он делает. Так будет полностью "по канонам" или можно еще оптимизировать/ исправить?

понятно что он делает: эмулирует работу find.
только очень криво и медленно.
всё это делается одной командой... но поля слушком узки, что-бы написать - какой именно (:
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
radial
Сообщения: 577
ОС: OpenSUSE

Re: Вхождение подстроки в строку

Сообщение radial »

вы правы лишь с эстетической точки зрения- все равно приложение стартует дольше, чем идет поиск- дольше в разы!
но именно с этой точки зрения мне и было интересно))
*пошел читать про find*
Спасибо сказали:
Аватара пользователя
radial
Сообщения: 577
ОС: OpenSUSE

Re: Вхождение подстроки в строку

Сообщение radial »

drBatty писал(а):
16.06.2010 20:36
понятно что он делает: эмулирует работу find.
только очень криво и медленно.
всё это делается одной командой... но поля слушком узки, что-бы написать - какой именно (:

не катит- find не ищет по содержимому файла. тогда уж бы про locate вспомнили что ли (но и с locate вариант очевидно не годен).
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Вхождение подстроки в строку

Сообщение drBatty »

radial писал(а):
16.06.2010 21:53
вы правы лишь с эстетической точки зрения- все равно приложение стартует дольше, чем идет поиск- дольше в разы!

да ладно!
это смотря сколько файлов.
radial писал(а):
17.06.2010 19:02
не катит- find не ищет по содержимому файла.

ищет. используйте -exec grep, или -exec sed.

PS: и где у вас тут поиск по содержанию? по содержанию имени? в find это есть. а вот по содержимому файла - действительно нет (есть по типу).
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: Вхождение подстроки в строку

Сообщение watashiwa_daredeska »

drBatty писал(а):
17.06.2010 21:01
и где у вас тут поиск по содержанию?
name="$(awk -F "=" '/Exec/ {print $2}' $file)"
Не? :)


drBatty писал(а):
16.06.2010 20:36
понятно что он делает
Счастливчик :) Мне что-то не очень понятно. В смысле, на пальцах, его полезная функция как-то не вырисовывается.
Спасибо сказали:
Аватара пользователя
radial
Сообщения: 577
ОС: OpenSUSE

Re: Вхождение подстроки в строку

Сообщение radial »

watashiwa_daredeska писал(а):
17.06.2010 21:36
drBatty писал(а):
16.06.2010 20:36
понятно что он делает
Счастливчик :) Мне что-то не очень понятно. В смысле, на пальцах, его полезная функция как-то не вырисовывается.

заменяет gnome-do и прочий ужоснах. Правда, желательно наличие Gnome-main-menu образца OpenSuse.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Вхождение подстроки в строку

Сообщение drBatty »

radial писал(а):
17.06.2010 22:17
gnome-do и прочий ужоснах

radial писал(а):
17.06.2010 22:17
Gnome-main-menu образца OpenSuse

не знаком со всем этим.
можно проще?
а) что на входе
б) что на выходе

подсказка:
обычно find -exec command
используют только для вызова command, но на самом деле, это ещё "фильтр" - т.е. значение опции -exec бывает истинно и ложно, в зависимости от результата command, потому вместо последней можно использовать grep -q {}, которая ищет по содержанию.
или даже sed -n 'script' {}, которая ещё и выполняет некий скрипт, и результат скрипта зависит от проверяемого файла (можно найти файлы, которые длиннее 35и строк, и содержат ровно 2 слова с тремя русскими буквами). ну и конечно - надо предусмотреть, что-бы sed не просматривала каждый файл целиком - устанете ждать.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали: