对于形如 someletters_12345_moreleters.ext 的文件名,我想提取其中的5位数字并将它们放入一个变量中。
明确一下细节,一个文件名的形式是若干个字符(不包含下划线),跟着一个五位的数字,数字两边都有一个下划线,最后跟着另一组若干个字符(不包含下划线)。我想要提取这个5位数字并将它存入一个变量中。
我非常感兴趣于完成这一目标的不同方法。
number=$(echo 'someletters_12345_subsequentchars.ext' | cut -d'_' -f 2)
echo $number
cut 是一个文本处理工具,用于按指定分隔符截取文件中的字段。-d '_' 参数指定使用下划线字符 (_) 作为字段分隔符。-f 2 参数表示提取第二个字段(字段索引从1开始计数)。number=$(echo 'someletters_12345_subsequentchars.ext' | awk -F'_' '{print $2}')
echo $number
-F'_' 参数指定了输入文本的分隔符为下划线字符 (_),这意味着 awk 将依据下划线来划分输入行中的字段。{print $2} 是 awk 脚本的一部分,其中 $2 表示输入行中的第二个字段(字段编号从1开始)。input="someletters_12345_subsequentchars.ext"
tmp=${input#*_}
number=${tmp%_*}
echo $number
tmp=${input#*_}: 这是 bash 中的参数扩展操作,# 符号在这里用于删除从左边开始匹配的第一个 _ 及其左边的所有字符。所以,tmp 变量将被赋值为 "12345_subsequentchars.ext",去掉了原字符串中从左开始的第一个 _ 及其之前的 someletters 部分。number=${tmp%_*}: 同样是 bash 的参数扩展操作,但这次 % 符号用于删除从右边开始匹配的第一个 _ 及其右边的所有字符。因此,number 变量将被赋值为 "12345",去掉了原字符串中从右开始的第一个 _ 及其之后的 subsequentchars.ext 部分。number=$(echo "someletters_12345_subsequentchars.ext" | tr -cd '[[:digit:]]')
echo $number
tr 是一个强大的字符转换命令,常用于替换或删除字符。-c 参数代表 complement(补集),告诉 tr 命令对指定字符集之外的字符进行操作。-d 参数代表 delete(删除),删除匹配到的字符。'[[:digit:]]' 是一个 POSIX 正则表达式的字符类,它匹配任何十进制数字(0-9)。number=$(echo "$filename" | grep -oE '[[:digit:]]{5}' | head -1)
echo $number
grep 是一个文本搜索工具,这里使用了-o选项,它仅输出匹配到的模式而非整行内容。-E 选项表示使用扩展正则表达式(ERE)。'[[:digit:]]{5}' 是一个正则表达式,匹配连续的任意五个数字字符。grep 会找出 $filename 中连续出现的任意五个数字,并只输出这些数字。head 命令用于显示文件或流的前几行,默认情况下显示头10行,但这里使用了 -1 选项,表示只显示第一行。总结起来,第一行命令的目的是从变量 $filename 所代表的字符串中找到第一个连续的五位数字序列,并将它存入 number 变量中。
参考:
相关阅读: