Intereting Posts

Альтернатива двойному кронштейну Bash Match

Дано

hasArgs=a:b:c: x=b if [[ ${hasArgs} = *$x:* ]] ; then … 

Хотелось бы заменить вышеуказанный тест в двойных скобках на менее специфичную для Bash альтернативу (то есть не использовать подоболочку / команду и т. Д.)

Расширение параметра не помогает, потому что оно не расходует переменные.

 if [ "${hasArgs}" != "${hasArgs#$x:}" ] ; then … 

Есть ли какое-нибудь простое (однострочное) решение, которое подойдет для этого варианта использования?

На самом деле, вы можете использовать стандартные расширения параметров здесь (вы просто пропустили подстановочный знак):

 $ args=a:b:c: $ x=b $ echo "${args%$x:*}" a: $ if [ "$args" != "${args#*$x:}" ]; then echo 'b: is present'; fi b: is present 

(или равно "${args%$x:*}" )

Недостатком является то, что вам нужно иметь двоеточие после b , поэтому a:b или обычный b не будут совпадать, и это также будет соответствовать a:bb:c . ( [[ $var = *$x:* ]] а также очевидное совпадение с case имеют тот же недостаток.)

Соответствие всем b , b:c , a:b , a:b:c , в то время как несоответствие a:bb:c было бы немного сложнее. Все, что я могу думать, это что-то вроде этого:

 args=a:b:c x=b IFS=: # affects globally set -f # affects globally... for x in $args; do if [ "$x" = "b" ]; then echo "b is present" fi done 

Если вы не хотите записать все дела:

 args=a:b:c x=b found=0 case "$args" in $x) found=1;; $x:*) found=1;; *:$x) found=1;; *:$x:*) found=1;; esac if [ "$found" = 1 ]; then ...; fi 

Гораздо проще с регулярными выражениями (в Bash):

 args=b:c x=b if [[ $args =~ (^|:)$x(:|$) ]]; then echo "b found" fi 

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

 hasArgs="a:b:c" x=b case "$hasArgs" in *$x*) echo "$x is present" ;; esac 

Следующее будет работать в sh:

 if echo "$hasArgs" | grep -q "$x"; then