最后一次出现下划线后从字符串中提取子字符串

时间:2018-09-10 03:21:56

标签: bash parameter-expansion

我在Linux shell中有一个字符串。该字符串中包含下划线。

我想从字符串中提取一个子字符串。

我想在下划线的第三次出现之后提取子字符串,从下划线开始算起。

file_name='email_Tracking_export_history_2018_08_15'
string_name="${file_name#*_*_*_}"
file_name2='email_Tracking_export_2018_08_15'
string_name2="${file_name2#*_*_*_}"

echo "$string_name"
echo "$string_name2"

结果

history_2018_08_15
2018_08_15

如您所见,string_name="${file_name#*_*_*_}"工作不正常。

所需结果:

2018_08_15
2018_08_15

我如何达到我想要的结果?

5 个答案:

答案 0 :(得分:2)

您可以在一个步骤中完成此操作,但这有点令人费解。设置文件名后

file_name='email_Tracking_export_history_2018_08_15'

我们得到的子字符串包含所有除了我们最终想要的东西:

$ echo "${file_name%_*_*_*}"
email_Tracking_export_history

这几乎是我们想要的,缺少下划线,因此我们添加:

$ echo "${file_name%_*_*_*}_"
email_Tracking_export_history_

现在我们知道我们必须从字符串开头删除什么,并将其插入到${word#pattern}扩展名中:

$ echo "${file_name#"${file_name%_*_*_*}_"}"
2018_08_15

或者我们将其分配给变量以供进一步使用:

string_name=${file_name#"${file_name%_*_*_*}_"}
              └───┬───┘ │  └───┬───┘ └─┬──┘  │
             outer word │  inner word  └────────inner pattern
                        └───outer pattern────┘

与第二个字符串类似。

答案 1 :(得分:0)

使用临时变量:

file_name='email_Tracking_export_history_2018_08_15'
temp="${file_name%_*_*_*}"
string_name="${file_name/${temp}_}"
file_name2='email_Tracking_export_2018_08_15'
temp="${file_name2%_*_*_*}"
string_name2="${file_name2/${temp}_}"

echo "$string_name"
echo "$string_name2"

答案 2 :(得分:0)

在bash中使用正则表达式如何:

#!/bin/bash

# Extract substring from string after 3rd occurrence in reverse
function extract() {
    if [[ "$1" =~ _([^_]+_[^_]+_[^_]+$) ]]; then
        echo "${BASH_REMATCH[1]}"
    fi
}

file_name='email_Tracking_export_history_2018_08_15'
string_name=$(extract $file_name)

file_name2='email_Tracking_export_2018_08_15'
string_name2=$(extract $file_name2)

echo "$string_name"
echo "$string_name2"

答案 3 :(得分:0)

% echo $file_name | rev | cut -f1-3 -d'_' | rev
2018_08_15
% echo $file_name2 | rev | cut -f1-3 -d'_' | rev
2018_08_15

rev反转字符串,使计数3个下划线的出现变得容易。然后,要提取的字符串部分将反转。

答案 4 :(得分:0)

expr是否已被禁止进入甚至最深的字符串匹配?

$ expr "$file_name" : '.*_\([^_]*_[^_]*_[^_]*\)'
2018_08_15
$ expr "$file_name2" : '.*_\([^_]*_[^_]*_[^_]*\)'
2018_08_15

来自https://www.tldp.org/LDP/abs/html/string-manipulation.html

expr "$string" : '.*\($substring\)'

    Extracts $substring at end of $string, where $substring is a regular expression.