Bash:以任何方式提取此字符串的第一部分?

时间:2016-03-18 15:27:12

标签: bash

我有一个日志,其中包含

等条目
touch_file_1:23_1786880:/home/user/project 

有没有办法只将“touch_file_123”部分提取到变量中?它后面的数字是一个inode,我想得到没有inode和尾随路径的文件名。

即使文件名中有下划线和数字,我也不想删掉那些,我只想截断最后一次下划线后跟数字。

请记住,我的原始文件名也可以包含冒号,我想保留文件中的所有冒号和下划线和数字

3 个答案:

答案 0 :(得分:1)

你可以这样做:

str='touch_file_1:11_2_3_1786880:/home/user/project'

echo "${str%_*}"
touch_file_1:11_2_3

"${str%_*}"将截断最后发生的下划线及其后面的所有内容。

答案 1 :(得分:1)

在参数扩展中,当使用最短模式匹配时,星号是非贪婪的。如果你需要的是从冒号之前的最后一个下划线中删除"到行的末尾",那么扩展你的glob就足够了:

$ a=( touch_file_1786880:/home/user/project foo_123_456_1786880:/tmp )
$ for f in "${a[@]}"; do echo "${f%_*:*}"; done
touch_file
foo_123_456

或者,如果条件是从冒号前的最后一个下划线中删除" 只捕获冒号的数字,那么任何字符到行的末尾",你可以用一个extglob来做。

$ shopt -s extglob
$ a=( touch_file_1786880:/home/user/project foo_123_456_1786880:/tmp )
$ for f in "${a[@]}"; do echo "${f%_+([0-9]):*}"; done
touch_file
foo_123_456

答案 2 :(得分:0)

如果你正在使用bash:

str='touch_file_1_2_3_1786880:/home/user/project'

[[ $str =~ (.*)_[0-9]*: ]] && printf '%s' ${BASH_REMATCH[1]}
touch_file_1_2_3

正则表达式(设置为shopt -s extglob)将检测以下划线(_)开头的数字字符串,后跟冒号(:)并捕获之前的内容:(。*)。< / p>

即使您的更新要求也可以正常运行:

str='touch_file_1:11_2_3_1786880:/home/user/project'
[[ $str =~ (.*)_[0-9]*: ]] && printf '%s' ${BASH_REMATCH[1]}
touch_file_1:11_2_3