Оператор IF возвращает true, если слово содержит определенную букву

В строковом литерале используйте двойную обратную косую черту, чтобы получить одиночную обратную косую черту в строке, которая передается в оболочку, что заставляет оболочку интерпретировать следующий символ буквально:

awk 'system("… ~/directory\\ with\\ spaces/subdirectory/")'

Чтобы процитировать ввод для использования во фрагменте оболочки, можно добавить обратную косую черту перед каждым символом. Портативный awk не упрощает эту задачу (в GNU awk есть расширения, которые делают это). В качестве альтернативы можно заключить каждый элемент в одинарные кавычки и заменить все одинарные кавычки в элементе на '\' '. Awk упрощает это решение: просто используйте gsub . Если ваш фрагмент кода awk находится в сценарии оболочки, вы можете использовать обратную косую черту-восьмеричный escape, чтобы поместить одинарную кавычку в строковый литерал awk.

<filenames.txt awk '{
    gsub(/\047/, /\047\\\047\047/, $0);
    system("ln -s \047" $0 "\047 ~/directory\\ with\\ spaces/subdirectory/");
}'
1
04.06.2017, 01:35
3 ответа

Старый (и вполне переносимый) способ сделать это — использовать оператор case:

var="information"
case $var in
     *i*) echo "An 'i' was found in $var";;
     * )  echo "There is no 'i' in $var";;
esac

Как одну строку function:

a="information"   b="i"

one(){ case $a in (*${b}*) true;; (*) false;; esac; }

И используется с:

if one; then 
    echo "Found %b in $a"; 
else
    echo "The character '$b' was not found in the string '$a'"
fi

Другими допустимыми способами выполнения той же проверки являются:

two(){ [[  $a ==   *"$b"*      ]] ; }   # Using a pattern match.
t33(){ [[  $a =~    "$b"       ]] ; }   # Extended Regex (ERE) match.
f44(){ [[  $a =~ ^.*"$b".*$    ]] ; }   # Using a ERE with limits.
f55(){ [[  ${a//[!"${b}"]}     ]] ; }   # Removing all non-matching chars.
six(){ [ ! "$a" = "${a%"$b"*}"  ] ; }   # Using char removal. 
s77(){ [[  $a =~ ^.*$          ]] ; }   # Testing if string is valid.

Все функции работают с допустимыми строками.
Временные параметры каждой функции для строк из 10, 100, 1000, …, 1000000 (1 миллион) символов приведены ниже:

        Number of characters in the string.
        10     100    1000    10000   100000  1000000
one  0.024m  0.036m  0.047m   0.207m   2.117m  25.363m
two  0.028m  0.030m  0.043m   0.179m   2.081m  25.337m
t33  0.044m  0.041m  0.053m   0.151m   1.757m  22.695m
f44  0.064m  0.075m  0.241m   1.864m  19.489m 198.488m
f55  0.055m  0.182m  5.275m 421.886m
six  0.043m  0.057m  0.297m  13.987m
s77  0.056m  0.061m  0.154m   1.201m  12.749m 134.774m

Количество символов создается путем повторения символа.
Тестируемая строка строится примерно так:

a="$1$(repeat "$2" 10**$k)$3"

Скрипт вызывается так:

$ ./script start a ending 

Функция f55 становится очень медленной, если размер обрабатываемой строки превышает (около) 1000 символы. То же самое происходит с функцией six для строк длиннее (около) 10000 (10k) символов.

Функция two работает быстрее для коротких строк, а t33 (регулярное выражение) лучше всего подходит для длинных строк.

Функции с t33 по s77 изменяют время выполнения, если выполняются как:

$ LANG=C ./script

Все становятся быстрее.

Интересно отметить, что функции f44 и s77 сообщат об ошибке *output false), если проверяемая строка является недопустимой строкой utf-8, например:

$'\x80abcde'

Точно так же, как это делает grep (базовая команда для регулярных выражений) (в локали utf-8):

$ echo $'\x80abcde' | grep '^.*$'       # no output

$ (LANG=C; echo $'\x80abcde' | grep '^.*$') 
�abcde
1
27.01.2020, 23:11

Как насчет использования switchили caseвот так:

#!/bin/sh

v="information"
case $v in
    *f*)
        echo "found \"f\" in ${v}";;
    *)
        echo "no match found in ${v}"
esac
exit

Обратите внимание, что если игла хранится в переменной, важно заключить ее в кавычки, чтобы она не воспринималась как образец:

case $haystack in
  *"$needle"*) echo match
esac

Без него, если бы $needleбыло, например, *или ?, это соответствовало бы любому стогу сена(и не -пустому стогу соответственно ).

В любом случае $needleне обязательно должен быть одиночным символом. Он будет работать с любой строкой.

Во многих оболочках это будет работать даже для любой последовательности не -нулевых байтов, даже если они не образуют допустимых символов, но не все будут разбивать символы. Например, байт 0xc3 не может быть найден таким образом в строке é, закодированной в UTF -8 (0xc3 0xa9 )в некоторых реализациях. И наоборот, некоторые оболочки могут найти iвнутри ξ, если локаль имеет кодировку BIG5 -HKSCS, где ξзакодировано как 0xa3 0x69 (, а iравно 0x69, как в ASCII ).

6
27.01.2020, 23:11

В условиях [[... ]]правая часть сравнения работает как образец.

if [[ $var == *i* ]] ; then
1
27.01.2020, 23:11

Теги

Похожие вопросы