给定someletters_12345_moreleters形式的文件名。ext,我想提取5位数字,并将它们放入一个变量。
为了强调这一点,我有一个x个字符的文件名,然后是一个5位数字序列,两边都有一个下划线,然后是另一组x个字符。我想把这个5位数代入一个变量。
我对实现这一目标的多种不同方式非常感兴趣。
给定someletters_12345_moreleters形式的文件名。ext,我想提取5位数字,并将它们放入一个变量。
为了强调这一点,我有一个x个字符的文件名,然后是一个5位数字序列,两边都有一个下划线,然后是另一组x个字符。我想把这个5位数代入一个变量。
我对实现这一目标的多种不同方式非常感兴趣。
当前回答
我的答案将对你想从字符串中得到什么有更多的控制。下面是如何从字符串中提取12345的代码
str="someletters_12345_moreleters.ext"
str=${str#*_}
str=${str%_more*}
echo $str
如果你想提取像abc这样的字符或像_或-这样的特殊字符,这样会更有效。例如:如果你的字符串是这样的,你想要someletters_之后和_moreleters之前的所有内容。ext:
str="someletters_123-45-24a&13b-1_moreleters.ext"
使用我的代码,您可以确切地说出您想要什么。 解释:
#*它将删除前面的字符串,包括匹配的键。这里我们提到的键是_ 它将删除以下字符串,包括匹配的键。这里我们提到的键是_more*
自己做一些实验,你会发现这很有趣。
其他回答
您可以使用参数展开来做到这一点。
如果a为常数,则下面的参数展开执行子字符串提取:
b=${a:12:5}
12是偏移量(从零开始),5是长度
如果数字周围的下划线是输入中唯一的下划线,您可以分两步分别去掉前缀和后缀:
tmp=${a#*_} # remove prefix ending in "_"
b=${tmp%_*} # remove suffix starting with "_"
如果有其他下划线,那么无论如何都可能是可行的,尽管比较棘手。如果有人知道如何在一个表达式中执行两个展开,我也想知道。
提出的两个解决方案都是纯bash,不涉及进程生成,因此非常快。
如果有人想要更严格的信息,你也可以像这样在man bash中搜索
$ man bash [press return key]
/substring [press return key]
[press "n" key]
[press "n" key]
[press "n" key]
[press "n" key]
结果:
${parameter:offset} ${parameter:offset:length} Substring Expansion. Expands to up to length characters of parameter starting at the character specified by offset. If length is omitted, expands to the substring of parameter start‐ ing at the character specified by offset. length and offset are arithmetic expressions (see ARITHMETIC EVALUATION below). If offset evaluates to a number less than zero, the value is used as an offset from the end of the value of parameter. Arithmetic expressions starting with a - must be separated by whitespace from the preceding : to be distinguished from the Use Default Values expansion. If length evaluates to a number less than zero, and parameter is not @ and not an indexed or associative array, it is interpreted as an offset from the end of the value of parameter rather than a number of characters, and the expan‐ sion is the characters between the two offsets. If parameter is @, the result is length positional parameters beginning at off‐ set. If parameter is an indexed array name subscripted by @ or *, the result is the length members of the array beginning with ${parameter[offset]}. A negative offset is taken relative to one greater than the maximum index of the specified array. Sub‐ string expansion applied to an associative array produces unde‐ fined results. Note that a negative offset must be separated from the colon by at least one space to avoid being confused with the :- expansion. Substring indexing is zero-based unless the positional parameters are used, in which case the indexing starts at 1 by default. If offset is 0, and the positional parameters are used, $0 is prefixed to the list.
bash解决方案:
IFS="_" read -r x digs x <<<'someletters_12345_moreleters.ext'
这将破坏一个名为x的变量。var x可以被更改为var _。
input='someletters_12345_moreleters.ext'
IFS="_" read -r _ digs _ <<<"$input"
基于jor的回答(这对我来说并不适用):
substring=$(expr "$filename" : '.*_\([^_]*\)_.*')
也许这可以帮助你得到想要的输出
代码:
your_number=$(echo "someletters_12345_moreleters.ext" | grep -E -o '[0-9]{5}')
echo $your_number
输出:
12345