简体   繁体   English

如何使用 Posix Shell 匹配 substring?

[英]How to match a substring using Posix Shell?

What's an idiomatic way to test if a string contains a substring in a Posix Shell?测试字符串是否在 Posix Shell 中包含 substring 的惯用方法是什么?

Basically this, but Posix:基本上是这样,但是 Posix:

[[ ${my_haystack} == *${my_needle}* ]]

Non-Posix Example非 Posix 示例

I'm looking for the equivalent of this, but that works in a Posix / Almquist / dash / ash shell:我正在寻找与此等效的方法,但这适用于 Posix / Almquist / dash / ash shell:

#!/bin/bash

set -e
set -u

find_needle() {
    my_haystack="${1}"
    my_needle="${2}"

    if [[ ${my_haystack} == *${my_needle}* ]]; then
        echo "'${my_haystack}' contains '${my_needle}'"
    else
        echo "'${my_haystack}' does NOT contain '${my_needle}'"
    fi
}

find_needle "${1:-"haystack"}" "${2:-"a"}"

(that doesn't work in sh ) (这在sh中不起作用)

My ideal solution would be one that doesn't require the use of a subshell or pipe, and that doesn't exit on failure in strict mode.我理想的解决方案是不需要使用子外壳或 pipe,并且在严格模式下不会在失败时退出。

Workaround解决方法

This works, but I'm wondering if there's another way to test a substring without echoing and piping to grep.这可行,但我想知道是否有另一种方法来测试 substring 而不回显和管道到 grep。

#!/bin/sh

set -e
set -u

find_needle() {
    my_haystack="${1}"
    my_needle="${2}"
    if echo "${my_haystack}" | grep -q "${my_needle}"; then
        echo "'${my_haystack}' contains '${my_needle}'"
    else
        echo "'${my_haystack}' does NOT contain '${my_needle}'"
    fi
}

find_needle "${1:-"haystack"}" "${2:-"a"}"

Or maybe this is the most idiomatic way?或者也许这最惯用的方式?

Substring match with case Substring 配case

As @dave_thompson_085 points out [ 1 ], you can use case :正如@dave_thompson_085 指出的[ 1 ],您可以使用case

case $haystack in
    *$needle*)
        return 0
        ;;
    *)
        return 1
        ;;
esac

Example Script示例脚本

  • ✅ no subshell ✅ 无子壳
  • ✅ no pipe ✅ 没有 pipe
  • ♂️ simplest, most idiomatic? ♂️ 最简单、最地道的? maybe也许
#!/bin/sh

set -e
set -u

test_substring() {
    haystack="${1}"
    needle="${2}"

    case $haystack in
        *$needle*)
            return 0
            ;;
        *)
            return 1
            ;;
    esac
}

find_needle() {
    my_haystack="${1}"
    my_needle="${2}"
    if test_substring "${my_haystack}" "${my_needle}"; then
        echo "'${my_haystack}' contains '${my_needle}'"
    else
        echo "'${my_haystack}' does NOT contain '${my_needle}'"
    fi
}

find_needle haystack a
find_needle haystack x

Output: Output:

'haystack' contains 'a'
'haystack' does NOT contain 'x'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM