IT story

POSIX sh에 문자열에 다른 문자열이 포함되어 있는지 어떻게 알 수 있습니까?

hot-time 2020. 7. 18. 09:58
반응형

POSIX sh에 문자열에 다른 문자열이 포함되어 있는지 어떻게 알 수 있습니까? [복제]


이 질문에는 이미 답변이 있습니다.

다른 문자열 안에 문자열이 있으면 다양한 논리를 수행하는 Unix 쉘 스크립트를 작성하고 싶습니다. 예를 들어, 특정 폴더에있는 경우 분기합니다. 누군가 이것을 달성하는 방법을 말해 줄 수 있습니까? 가능하다면 나는 이것을 쉘 특정이 아닌 것으로 만들고 싶습니다 (즉, bash만이 아닙니다). 다른 방법이 없다면 그렇게 할 수 있습니다.

#!/usr/bin/env sh

if [ "$PWD" contains "String1" ]
then
    echo "String1 present"
elif [ "$PWD" contains "String2" ]
then
    echo "String2 present"
else
    echo "Else"
fi

여기 또 다른 해결책이 있습니다. 이 사용 POSIX 하위 문자열 매개 변수 확장을 가 bash는, 대시, KSH에서 작동, 그래서 ...

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

편집 : 좋은 생각입니다, C. Ross. 다음은 몇 가지 예가 포함 된 기능화 된 버전입니다.

# 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"

순수한 POSIX 쉘 :

#!/bin/sh
CURRENT_DIR=`pwd`

case "$CURRENT_DIR" in
  *String1*) echo "String1 present" ;;
  *String2*) echo "String2 present" ;;
  *)         echo "else" ;;
esac

Extended shells like ksh or bash have fancy matching mechanisms, but the old-style case is surprisingly powerful.


Sadly, I am not aware of a way to do this in sh. However, using bash (starting in version 3.0.0, which is probably what you have), you can use the =~ operator like this:

#!/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

As an added bonus (and/or a warning, if your strings have any funny characters in them), =~ accepts regexes as the right operand if you leave out the quotes.


#!/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

Here is a link to various solutions of your issue.

This is my favorite as it makes the most human readable sense:

The Star Wildcard Method

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

case $(pwd) in
  *path) echo "ends with path";;
  path*) echo "starts with path";;
  *path*) echo "contains path";;
  *) echo "this is the default";;
esac

There's bash regexps. Or there's 'expr':

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

See the manpage for the 'test' program. If you're just testing for the existence of a directory you would normally do something like so:

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

If you're actually trying to match a string you can use bash expansion rules & wildcards as well:

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

If you need to do something more complex you'll need to use another program like expr.


In special cases where you want to find whether a word is contained in a long text, you can iterate through the long text with a 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

This is pure Bourne shell.


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

--> output: String 1 contain string 2


If you want a ksh only method that is as fast as "test", you can do something like:

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

It works by deleting the needle in the haystack and then comparing the string length of old and new haystacks.

참고URL : https://stackoverflow.com/questions/2829613/how-do-you-tell-if-a-string-contains-another-string-in-posix-sh

반응형