给定someletters_12345_moreleters形式的文件名。ext,我想提取5位数字,并将它们放入一个变量。
为了强调这一点,我有一个x个字符的文件名,然后是一个5位数字序列,两边都有一个下划线,然后是另一组x个字符。我想把这个5位数代入一个变量。
我对实现这一目标的多种不同方式非常感兴趣。
给定someletters_12345_moreleters形式的文件名。ext,我想提取5位数字,并将它们放入一个变量。
为了强调这一点,我有一个x个字符的文件名,然后是一个5位数字序列,两边都有一个下划线,然后是另一组x个字符。我想把这个5位数代入一个变量。
我对实现这一目标的多种不同方式非常感兴趣。
当前回答
如果我们关注以下概念: 一串(一个或几个)数字。
我们可以使用一些外部工具来提取这些数字。 我们可以很容易地擦除所有其他字符,无论是sed还是tr:
name='someletters_12345_moreleters.ext'
echo $name | sed 's/[^0-9]*//g' # 12345
echo $name | tr -c -d 0-9 # 12345
但如果$name包含几组数字,则上述操作将失败:
如果“name = someletters_12345_moreleters_323_end。ext”,那么:
echo $name | sed 's/[^0-9]*//g' # 12345323
echo $name | tr -c -d 0-9 # 12345323
我们需要使用正则表达式。 在sed和perl中只选择第一次运行(12345而不是323):
echo $name | sed 's/[^0-9]*\([0-9]\{1,\}\).*$/\1/'
perl -e 'my $name='$name';my ($num)=$name=~/(\d+)/;print "$num\n";'
但我们也可以直接在bash(1)中执行:
regex=[^0-9]*([0-9]{1,}).*$; \
[[ $name =~ $regex ]] && echo ${BASH_REMATCH[1]}
这允许我们提取任意长度的数字的第一行 被其他文本/字符包围。
注意:正则表达式=[^ 0 - 9]*([0 - 9]{5,5})。*美元;将只匹配精确的5位数运行。:-)
(1):每段短文本都比调用外部工具快。并不比在sed或awk中处理大文件快。
其他回答
如果有人想要更严格的信息,你也可以像这样在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.
没有任何子过程,您可以:
shopt -s extglob
front=${input%%_+([a-zA-Z]).*}
digits=${front##+([a-zA-Z])_}
一个非常小的变体也可以在ksh93中工作。
还有bash内置的'expr'命令:
INPUT="someletters_12345_moreleters.ext"
SUBSTRING=`expr match "$INPUT" '.*_\([[:digit:]]*\)_.*' `
echo $SUBSTRING
试着用cut -c startindex - stopindx
我的答案将对你想从字符串中得到什么有更多的控制。下面是如何从字符串中提取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*
自己做一些实验,你会发现这很有趣。