В строковом литерале используйте двойную обратную косую черту, чтобы получить одиночную обратную косую черту в строке, которая передается в оболочку, что заставляет оболочку интерпретировать следующий символ буквально:
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/");
}'
Старый (и вполне переносимый) способ сделать это — использовать оператор 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
Как насчет использования 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 ).
В условиях [[... ]]
правая часть сравнения работает как образец.
if [[ $var == *i* ]] ; then