AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 525357
Accepted
TomRoche
TomRoche
Asked: 2019-06-17 23:37:12 +0800 CST2019-06-17 23:37:12 +0800 CST 2019-06-17 23:37:12 +0800 CST

bash `case` 语句将输入分类为非整数和整数

  • 772

摘要:我想使用一个bash case语句(在其他代码中)对输入进行分类,以确定它们是否是

  • 一个正整数
  • 一个负整数
  • 零
  • 一个空字符串
  • 一个非整数字符串

可执行代码如下,正确分类以下输入:

  • ''
  • word
  • a\nmultiline\nstring
  • 2.1
  • -3

但是将以下两者都归类为...负整数:-(

  • 0
  • 42

细节:

将以下内容保存到文件(例如/tmp/integer_case_statement.sh)中chmod,然后运行它:

#!/usr/bin/env bash

### This should be a simple `bash` `case` statement to classify inputs as
### {positive|negative|zero|non-} integers.
### Trying extglob, since my previous integer-match patterns failed.
### Gotta turn that on before *function definition* per https://stackoverflow.com/a/34913651/915044
shopt -s extglob

declare cmd=''

function identify() {
    local -r it=${1}  # no quotes in case it's multiline
#    shopt -s extglob # can't do that here
    case ${it} in
        '')
            # empty string, no need for `if [[ -z ...`
            >&2 echo 'ERROR: null arg'
            ;;
        ?(-|+)+([[:digit:]]))
            # it's an integer, so just say so and fallthrough
            >&2 echo 'DEBUG: int(it), fallthrough'
            ;&
        -+([[:digit:]]))
            # it's negative: just return it
            >&2 echo 'DEBUG: int(it) && (it < 0), returning it'
            echo "${it}"
            ;;
        0)
            # it's zero: that's OK
            >&2 echo 'DEBUG: int(it) && (it == 0), returning it'
            echo '0'
            ;;
        ++([[:digit:]]))
            # it's positive: just return it
            >&2 echo 'DEBUG: int(it) && (it > 0), returning it'
            echo "${it}"
            ;;
        *)
            # not an integer, just return it
            >&2 echo 'DEBUG: !int(it)'
            echo "${it}"
            ;;
    esac
} # end function identify

echo -e "'bash --version'==${BASH_VERSION}\n"

echo "identify '':"
identify ''
echo
# > ERROR: null arg

echo 'identify word:'
identify word
echo
# > DEBUG: !int(it)
# > word

echo 'identify a
multiline
string:'
identify 'a
multiline
string'
echo
# > DEBUG: !int(it)
# > a
# > multiline
# > string

echo 'identify 2.1:'
identify 2.1
echo
# > DEBUG: !int(it)
# > 2.1

echo 'identify -3:'
identify -3
echo
# > DEBUG: int(it), fallthrough
# > DEBUG: int(it) && (it < 0), returning it
# > -3

echo 'identify 0:'
identify 0
echo
# > DEBUG: int(it), fallthrough
# > DEBUG: int(it) && (it < 0), returning it
# > 0

echo 'identify 42:'
identify 42
echo
# > DEBUG: int(it), fallthrough
# > DEBUG: int(it) && (it < 0), returning it
# > 42

exit 0

当前输出被内联在文件中,但为了便于阅读,这里单独列出我当前的输出:

'bash --version'==4.3.30(1)-release

identify '':
ERROR: null arg

identify word:
DEBUG: !int(it)
word

identify a
multiline
string:
DEBUG: !int(it)
a
multiline
string

identify 2.1:
DEBUG: !int(it)
2.1

identify -3:
DEBUG: int(it), fallthrough
DEBUG: int(it) && (it < 0), returning it
-3

identify 0:
DEBUG: int(it), fallthrough
DEBUG: int(it) && (it < 0), returning it
0

identify 42:
DEBUG: int(it), fallthrough
DEBUG: int(it) && (it < 0), returning it
42

后两个输入是我的问题:为什么 case 语句识别

  • 0 作为负整数(而不是 0)
  • 42 作为负整数(而不是正整数)

? 感谢您的帮助。

bash wildcards
  • 1 1 个回答
  • 1378 Views

1 个回答

  • Voted
  1. Best Answer
    TomRoche
    2019-06-18T20:32:11+08:002019-06-18T20:32:11+08:00

    总结:感谢

    • 弗罗斯特舒茨s/;&/;;&/
    • 弗雷迪正确的正整数模式(猜我只是夜盲症)

    我还添加了一个附加子句来检测带符号的零,以及更多的测试用例。

    细节:

    将此改进后的代码保存到文件(例如/tmp/integer_case_statement.sh)中chmod,然后运行它:

    #!/usr/bin/env bash
    
    ### Simple `bash` `case` statement to classify inputs as {positive|negative|zero|non-} integers.
    ### Trying extglob, since my previous integer-match patterns failed.
    ### Gotta turn that on before *function definition* per https://stackoverflow.com/a/34913651/915044
    shopt -s extglob
    
    declare input=''
    
    ### For `case` *patterns* (NOT regexps), see
    ### https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html
    function identify() {
        local -r it=${1}  # no quotes in case it's multiline
    #    shopt -s extglob # can't do that here
        case ${it} in
            '')
                # empty string, no need for `if [[ -z ...`
                >&2 echo 'ERROR: null arg'
                ;;
            [+-]0)
                >&2 echo 'ERROR: zero should not be signed'
                ;;
            ?(-|+)+([[:digit:]]))
                # it's an integer, so just say so and fallthrough
                >&2 echo 'DEBUG: int(it), fallthrough'
    #            ;& # this only runs the next clause, thanks https://unix.stackexchange.com/users/30851/frostschutz
                ;;& # works
            -+([[:digit:]]))
                >&2 echo 'DEBUG: it < 0'
                ;;
            0)
                >&2 echo 'DEBUG: it == 0'
                echo '0'
                ;;
            ?(+)+([[:digit:]])) # thanks https://unix.stackexchange.com/users/332764/freddy
                >&2 echo 'DEBUG: it > 0'
                ;;
            *)
                >&2 echo 'DEBUG: !int(it)'
                ;;
        esac
    } # end function identify
    
    echo -e "'bash --version'==${BASH_VERSION}\n"
    
    for input in \
        '' \
        '@#$%^&!' \
        'word' \
        'a
    multiline
    string' \
        '2.1' \
        '-3' \
        '+3' \
        '+0' \
        '0' \
        '-0' \
        '42' \
    ; do
        echo "identify '${input}'"
        identify "${input}"
        ret_val="${?}"
        if [[ "${ret_val}" -ne 0 ]] ; then
            >&2 echo "ERROR: retval='${ret_val}', exiting ..."
            exit 3
        fi
        echo # newline
    done
    
    exit 0
    

    在这个 Debian 工作站上,上面的当前输出:

    'bash --version'==4.3.30(1)-release
    
    identify ''
    ERROR: null arg
    
    identify '@#$%^&!'
    DEBUG: !int(it)
    
    identify 'word'
    DEBUG: !int(it)
    
    identify 'a
    multiline
    string'
    DEBUG: !int(it)
    
    identify '2.1'
    DEBUG: !int(it)
    
    identify '-3'
    DEBUG: int(it), fallthrough
    DEBUG: it < 0
    
    identify '+3'
    DEBUG: int(it), fallthrough
    DEBUG: it > 0
    
    identify '+0'
    ERROR: zero should not be signed
    
    identify '0'
    DEBUG: int(it), fallthrough
    DEBUG: it == 0
    0
    
    identify '-0'
    ERROR: zero should not be signed
    
    identify '42'
    DEBUG: int(it), fallthrough
    DEBUG: it > 0
    

    感谢您的帮助!

    • 2

相关问题

  • 通过命令的标准输出以编程方式导出环境变量[重复]

  • 从文本文件传递变量的奇怪问题

  • 虽然行读取保持转义空间?

  • `tee` 和 `bash` 进程替换顺序

  • 运行一个非常慢的脚本直到它成功

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve