Как проверить, содержит ли строка подстроку в тире или золе?

Вот что я делаю:

#!/bin/sh contains() { if $(echo $1 | grep -c $2) ; then echo "0" # contains else echo "1" # not contains fi } myString=$1 mySubsting=$2 contains $myString '$mySubsting' 

Вот пример выполнения:

 # sh ./myScript abcdef bc ./myTest: line 3: 0: command not found 1 

Редакция:

Исходный вопрос: Как проверить, содержит ли строка подстроку в Bourne Shell?

Вот что я делаю:

  #!/bin/sh if echo $1 | grep -q $2 then echo "0" else echo "1" fi 

Вот пример выполнения:

 $ sh ./myTest "$(systemctl status ntp)" "Active: active" grep: active: No such file or directory 1 

Как правильно проверить, содержит ли одна строка другую?

2 Solutions collect form web for “Как проверить, содержит ли строка подстроку в тире или золе?”

Для этого была построена оболочка Борна. Это то же самое, что и в современных sh (что больше похоже на то, что вы используете, у оболочки Bourne не было поддержки $(...) , если это была оболочка Bourne, вы получили бы другую ошибку):

 case $1 in *"$2"*) printf '"%s" is in "%s"\n' "$2" "$1" esac 

Если вы хотите использовать grep , это будет:

 if printf '%s\n' "$1" | grep -Fqe "$2"; then printf '"%s" is in "%s"\n' "$2" "$1" fi 

Или

 if grep -Fqe "$2" << EOF $1 EOF then printf '"%s" is in "%s"\n' "$2" "$1" fi 

Но это будет работать только в том случае, если $2 содержать символ новой строки.

В любом случае вам нужны кавычки в большинстве случаев расширения параметров. Единственное место, где это не нужно, – это в этом case $1 выше, но даже тогда case "$1" не повредит.

Несколько заметок в вашем коде:

  1. Вы не можете использовать echo для произвольных строк . Здесь, в зависимости от реализации echo , он будет терпеть неудачу для значений $1 таких как -n или foo\bar .
  2. Оставляя разложение параметров без кавычек, имеет особое значение в оболочках . Вы не хотите этого делать. Попробуйте, например, что grep -c $2 со значением $2 как * или root /etc/passwd .
  3. grep без -F для соответствия регулярных выражений. Вам нужен -F для поиска фиксированной строки (подстроки) (используется для fgrep ), но опять же, если $2 содержит несколько строк, что говорит grep -F для поиска любого содержимого этих строк на входе ( grep -F $'a\nb' будет искать a или b , а не строку $'a\nb' ).
  4. В grep -c $2 содержимое $2 будет принято в качестве опции, если оно началось с - . Чтобы избежать этого, вы хотите использовать grep -c -e "$2" или grep -c -- "$2" .
  5. Вы хотите использовать статус выхода, а не stdout, чтобы сообщать о булевых условиях. В сценариях с exit ( exit 0 для true, exit 1 (или любое ненулевое число, но избегайте значений, превышающих 120) для false). Для функций вместо этого используйте return . Хотя оба скрипта и функции будут возвращаться со статусом последней команды запуска.
  6. $(cmd) расширяется до выхода cmd (и претерпевает split + glob здесь из-за недостающих кавычек) минус конечные символы новой строки. Поэтому, если cmd выводит 0\n , $(cmd) расширяется до 0 . Таким образом, запуск $(cmd) пытается запустить команду с именем 0 . Если вы хотите преобразовать вывод cmd в состояние выхода (поэтому его можно использовать как логическое), вам нужно (exit "$(cmd)") . Это запускает подоболочку, которая выходит с выходом cmd качестве кода выхода).
  7. grep -c подсчитывает количество вхождений. Здесь вам не нужно иметь полный счет, вам нужно только знать, если он найден вообще (если есть хотя бы одно совпадение). Для этого grep -q более эффективен, так как он прекращает поиск после его обнаружения. Для древних реализаций grep которые не поддерживают (стандартный) -q вариант, вы можете использовать fgrep -le "$2" > /dev/null . С -l , fgrep также останавливается на первом совпадении, но выводит имя файла (которое мы отбрасываем здесь, перенаправляя вывод в /dev/null ).

bash поддерживает это изначально;

 $ string1="abcmoocow" $ string2="moo" $ if [[ $string1 == *$string2* ]]; then echo "Match"; else echo "No Match"; fi Match $ string1="abccrowcow" $ if [[ $string1 == *$string2* ]]; then echo "Match"; else echo "No Match"; fi No Match 

также исправить ваш пример; изменение;

 if $(echo $1 | grep -c $2) ; then 

становиться:

 if [ -n "$(echo $1 | grep -c $2)" ]; then 

(проверяет, возвращает ли grep любые данные)

также обратите внимание, что также возможно работать с кодом выхода;

 $ echo bob | grep "o" &>/dev/null; echo $? 0 $ echo bob | grep "z" &>/dev/null; echo $? 1 
  • добавьте подкаталоги в $ PATH в bash, используя find
  • Разбор JSON на оболочке
  • Есть ли простой способ получить массив всех аргументов, которые не начинаются с дефиса?
  • Как извлечь дату и рассчитать, находится ли она в течение «х» дней с сегодняшнего дня?
  • grep окружающие символы матча
  • Число новых строк в строке как целое
  • Объединение команд строк и grep: как ограничить результаты строками с нулевым завершением
  • извлекать часть текста из всех совпадающих строк
  • Может ли bash развернуть цитированную и / или экранированную строковую переменную в слова?
  • Изменение вхождения строки в файл при соблюдении новых строк строки DOS
  • Проверьте, содержит ли строка строку подстроки
  • Linux и Unix - лучшая ОС в мире.