Shell脚本中如何从tar文件名提取.tar前的数字
可行的实现方法
方法1:Bash内置参数替换(推荐,无需外部命令)
直接用Bash自带的字符串处理能力,不用调用sed、grep这类外部工具,效率更高:
# 先移除文件名末尾的.tar后缀 FILE_NO_TAR="${FILE%.tar}" # 提取后缀移除后字符串末尾的连续数字 PROCESS_NUMBER="${FILE_NO_TAR##*[!0-9]}" export PROCESS_NUMBER
原理:
${FILE%.tar}:删除FILE变量末尾最短的.tar字符串,得到不带后缀的文件名(比如application-2412-test-12312333)${FILE_NO_TAR##*[!0-9]}:删除FILE_NO_TAR中从开头到最后一个非数字字符的所有内容,剩下的就是目标数字串
方法2:使用sed扩展正则
通过sed -E启用扩展正则,精准匹配.tar前的最后一段连续数字:
export PROCESS_NUMBER=$(echo "$FILE" | sed -E 's/.*([0-9]+)\.tar/\1/')
如果文件名是纯数字加.tar(比如1234.tar),上述命令会失效,可修改为:
export PROCESS_NUMBER=$(echo "$FILE" | sed -E 's/(.*[^0-9])?([0-9]+)\.tar/\2/')
原理:
-E:让sed支持扩展正则,不用对括号()和加号+转义.*([0-9]+)\.tar:贪婪匹配所有内容直到.tar前的连续数字,捕获该数字串作为输出结果
方法3:使用grep正向预查
利用grep的Perl正则特性,直接提取.tar前的数字:
export PROCESS_NUMBER=$(echo "$FILE" | grep -oP '\d+(?=\.tar)')
原理:
-o:只输出匹配到的部分-P:启用Perl兼容正则表达式\d+(?=\.tar):匹配一个或多个数字,且数字后面紧跟.tar(正向预查不会把.tar包含在结果里)
之前命令失败的原因
- 第一个sed命令:没启用扩展正则,
+在基本正则里要转义成\+才会生效;即便转义,若文件名有多段数字,贪婪匹配逻辑也可能出错(启用扩展正则后该命令可正常工作) - 第二个sed命令:没启用扩展正则,
()和+被当成普通字符处理,根本匹配不到数字段 - 第三个sed命令:会捕获文件名里第一个出现的连续数字,而不是
.tar前的最后一段,不符合需求 - 第四个sed命令:只匹配
-后面的数字,要是数字前面没有-(比如application-test123.tar)就匹配不到,适用范围太窄
内容的提问来源于stack exchange,提问作者xttx
相关产品推荐
相关产品推荐

