如何在 Bash 中使用正负索引获取子字符串

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7354017/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 00:44:17  来源:igfitidea点击:

How to Get a Substring Using Positive and Negative Indexes in Bash

bashunix

提问by Eli

What I want is pretty simple. Given a string 'this is my test string,' I want to return the substring from the 2nd position to the 2nd to last position. Something like: substring 'this is my test string' 1,-1. I know I can get stuff from the beginning of the string using cut, but I'm not sure how I can calculate easily from the end of the string. Help?

我想要的很简单。给定一个字符串“这是我的测试字符串”,我想将子字符串从第二个位置返回到第二个到最后一个位置。类似的东西: substring 'this is my test string' 1,-1。我知道我可以使用 cut 从字符串的开头获取内容,但我不确定如何从字符串的末尾轻松计算。帮助?

回答by Eli

Turns out I can do this with awk pretty easily as follows:

结果我可以很容易地用 awk 做到这一点,如下所示:

echo 'this is my test string' | awk '{ print substr( $0, 2, length($0)-2 ) }'

echo 'this is my test string' | awk '{ print substr( $0, 2, length($0)-2 ) }'

回答by AlG

Be cleaner in awk, python, perl, etc. but here's one way to do it:

在 awk、python、perl 等中更简洁,但这是一种方法:

#!/usr/bin/bash

msg="this is my test string"
start=2
len=$((${#msg} - ${start} - 2))

echo $len

echo ${msg:2:$len}

results in is is my test stri

结果是 is is my test stri

回答by bash-o-logist

You can do this with just pure bash

你可以用纯粹的 bash

$ string="i.am.a.stupid.fool.are.you?"
$ echo ${string:  2:$((${#string}-4))}
am.a.stupid.fool.are.yo

回答by l0b0

Look ma, no global variables or forks (except for the obvious printf) and thoroughly tested:

看 ma,没有全局变量或分叉(除了明显的printf)并经过彻底测试:

substring()
{
    # Extract substring with positive or negative indexes
    # @param : String
    # @param : Start (default start of string)
    # @param : Length (default until end of string)

    local -i strlen="${#1}"
    local -i start="${2-0}"
    local -i length="${3-${#1}}"

    if [[ "$start" -lt 0 ]]
    then
        let start+=$strlen
    fi

    if [[ "$length" -lt 0 ]]
    then
        let length+=$strlen
        let length-=$start
    fi

    if [[ "$length" -lt 0 ]]
    then
        return
    fi

    printf %s "${1:$start:$length}"
}