Como você diz se uma string contém outra string no POSIX sh?

Eu quero escrever um script shell Unix que fará várias lógicas se houver uma string dentro de outra string. Por exemplo, se eu estiver em uma determinada pasta, ramifique-se. Alguém poderia me dizer como fazer isso? Se possível eu gostaria de fazer isso não específico do shell (ou seja, não apenas bash), mas se não há outra maneira, eu posso me virar com isso.

#!/usr/bin/env sh if [ "$PWD" contains "String1" ] then echo "String1 present" elif [ "$PWD" contains "String2" ] then echo "String2 present" else echo "Else" fi 

Aqui está outra solução. Isso usa expansão de parâmetro de substring POSIX , então ele funciona em bash, dash, ksh …

 test "${string#*$word}" != "$string" && echo "$word found in $string" 

Edit: Essa é uma ótima idéia, C. Ross. Aqui está uma versão funcionalizada com alguns exemplos:

 # contains(string, substring) # # Returns 0 if the specified string contains the specified substring, # otherwise returns 1. contains() { string="$1" substring="$2" if test "${string#*$substring}" != "$string" then return 0 # $substring is in $string else return 1 # $substring is not in $string fi } contains "abcd" "e" || echo "abcd does not contain e" contains "abcd" "ab" && echo "abcd contains ab" contains "abcd" "bc" && echo "abcd contains bc" contains "abcd" "cd" && echo "abcd contains cd" contains "abcd" "abcd" && echo "abcd contains abcd" contains "" "" && echo "empty string contains empty string" contains "a" "" && echo "a contains empty string" contains "" "a" || echo "empty string does not contain a" contains "abcd efgh" "cd ef" && echo "abcd efgh contains cd ef" contains "abcd efgh" " " && echo "abcd efgh contains a space" 

Puro shell POSIX:

 #!/bin/sh CURRENT_DIR=`pwd` case "$CURRENT_DIR" in *String1*) echo "String1 present" ;; *String2*) echo "String2 present" ;; *) echo "else" ;; esac 

Shells estendidos como ksh ou bash possuem mecanismos de combinação sofisticados, mas o case estilo antigo é surpreendentemente poderoso.

Infelizmente, eu não estou ciente de uma maneira de fazer isso em sh. No entanto, usando o bash (começando na versão 3.0.0, que é provavelmente o que você tem), você pode usar o operador = ~ assim:

 #!/bin/bash CURRENT_DIR=`pwd` if [[ "$CURRENT_DIR" =~ "String1" ]] then echo "String1 present" elif [[ "$CURRENT_DIR" =~ "String2" ]] then echo "String2 present" else echo "Else" fi 

Como um bônus adicional (e / ou um aviso, se suas strings tiverem algum caractere engraçado nelas), = ~ aceita regexes como o operando da direita se você deixar de fora as aspas.

 #!/usr/bin/env sh # Searches a subset string in a string: # 1st arg:reference string # 2nd arg:subset string to be matched if echo "$1" | grep -q "$2" then echo "$2 is in $1" else echo "$2 is not in $1" fi 
 case $(pwd) in *path) echo "ends with path";; path*) echo "starts with path";; *path*) echo "contains path";; *) echo "this is the default";; esac 

Aqui está um link para várias soluções do seu problema.

Este é o meu favorito, pois faz o sentido mais legível para humanos:

O método Star Wildcard

 if [[ "$string" == *"$substring"* ]]; then return 1 fi return 0 

Há expressões regulares . Ou há ‘expr’:

  if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG=`dirname "$PRG"`/"$link" fi 

Veja a manpage do programa ‘teste’. Se você está apenas testando a existência de um diretório, você normalmente faria algo assim:

 if test -d "String1"; then echo "String1 present" end 

Se você está realmente tentando combinar uma string, você pode usar as regras de expansão do bash e curingas também:

 if test -d "String*"; then echo "A directory starting with 'String' is present" end 

Se você precisar fazer algo mais complexo, precisará usar outro programa como o expr.

Em casos especiais em que você deseja descobrir se uma palavra está contida em um texto longo, é possível percorrer o texto longo com um loop.

 found=F query_word=this long_string="many many words in this text" for w in $long_string; do if [ "$w" = "$query_word" ]; then found=T break fi done 

Isso é puro shell Bourne.

 test $(echo "stringcontain" "ingcon" |awk '{ print index($1, $2) }') -gt 0 && echo "String 1 contain string 2" 

-> output: A string 1 contém a string 2

Se você quiser apenas um método ksh que seja tão rápido quanto “teste”, você pode fazer algo como:

 contains() # haystack needle { haystack=${1/$2/} if [ ${#haystack} -ne ${#1} ] ; then return 1 fi return 0 } 

Funciona eliminando a agulha no palheiro e comparando o comprimento das cordas de antigos e novos palheiros.