给定someletters_12345_moreleters形式的文件名。ext,我想提取5位数字,并将它们放入一个变量。
为了强调这一点,我有一个x个字符的文件名,然后是一个5位数字序列,两边都有一个下划线,然后是另一组x个字符。我想把这个5位数代入一个变量。
我对实现这一目标的多种不同方式非常感兴趣。
给定someletters_12345_moreleters形式的文件名。ext,我想提取5位数字,并将它们放入一个变量。
为了强调这一点,我有一个x个字符的文件名,然后是一个5位数字序列,两边都有一个下划线,然后是另一组x个字符。我想把这个5位数代入一个变量。
我对实现这一目标的多种不同方式非常感兴趣。
当前回答
通用解决方案,其中数字可以在文件名中的任何位置,使用这样的序列中的第一个:
number=$(echo $filename | egrep -o '[[:digit:]]{5}' | head -n1)
另一个精确提取变量一部分的解决方案:
number=${filename:offset:length}
如果你的文件名总是使用stuff_digits_…你可以使用awk:
number=$(echo $filename | awk -F _ '{ print $2 }')
还有一种方法可以删除除数字以外的所有内容,使用
number=$(echo $filename | tr -cd '[[:digit:]]')
其他回答
这里是纯参数替换,一个空字符串。注意,我只将一些字母和更多字母定义为字符。如果它们是字母数字,这将无法正常工作。
filename=someletters_12345_moreletters.ext
substring=${filename//@(+([a-z])_|_+([a-z]).*)}
echo $substring
12345
也许这可以帮助你得到想要的输出
代码:
your_number=$(echo "someletters_12345_moreleters.ext" | grep -E -o '[0-9]{5}')
echo $your_number
输出:
12345
如果我们关注以下概念: 一串(一个或几个)数字。
我们可以使用一些外部工具来提取这些数字。 我们可以很容易地擦除所有其他字符,无论是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中处理大文件快。
我喜欢sed处理正则表达式组的能力:
> var="someletters_12345_moreletters.ext"
> digits=$( echo "$var" | sed "s/.*_\([0-9]\+\).*/\1/p" -n )
> echo $digits
12345
一个更一般的选择是不要假设你用下划线_标记你的数字序列的开始,因此例如剥离你在你的序列之前得到的所有非数字:s/[^0-9]\+\([0-9]\+\).*/\1/p。
> man sed | grep s/regexp/replacement -A 2
s/regexp/replacement/
Attempt to match regexp against the pattern space. If successful, replace that portion matched with replacement. The replacement may contain the special character & to
refer to that portion of the pattern space which matched, and the special escapes \1 through \9 to refer to the corresponding matching sub-expressions in the regexp.
更多关于这一点,以防你对regexp不太自信:
S代表_s_substitute [0-9]+匹配1+数字 \1链接到正则表达式输出的组n.1(组0是整个匹配,组1是括号内的匹配) P标志为_p_printing
所有转义\都是为了使sed的regexp处理工作。
Inklusive end,类似于JS和Java实现。删除+1如果你不想这样做。
function substring() {
local str="$1" start="${2}" end="${3}"
if [[ "$start" == "" ]]; then start="0"; fi
if [[ "$end" == "" ]]; then end="${#str}"; fi
local length="((${end}-${start}+1))"
echo "${str:${start}:${length}}"
}
例子:
substring 01234 0
01234
substring 012345 0
012345
substring 012345 0 0
0
substring 012345 1 1
1
substring 012345 1 2
12
substring 012345 0 1
01
substring 012345 0 2
012
substring 012345 0 3
0123
substring 012345 0 4
01234
substring 012345 0 5
012345
更多示例调用:
substring 012345 0
012345
substring 012345 1
12345
substring 012345 2
2345
substring 012345 3
345
substring 012345 4
45
substring 012345 5
5
substring 012345 6
substring 012345 3 5
345
substring 012345 3 4
34
substring 012345 2 4
234
substring 012345 1 3
123