从倒数第三个下划线出现后的字符串中提取子字符串
Extract substring from string after third last occurrence of underscore
我在 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
我怎样才能达到我想要的结果?
使用临时变量:
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"
如何在 bash 中使用正则表达式:
#!/bin/bash
# Extract substring from string after 3rd occurrence in reverse
function extract() {
if [[ "" =~ _([^_]+_[^_]+_[^_]+$) ]]; 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"
您可以一步完成,但有点复杂。设置文件名后
file_name='email_Tracking_export_history_2018_08_15'
我们得到包含所有内容的子字符串除了我们最后想要的内容:
$ echo "${file_name%_*_*_*}"
email_Tracking_export_history
这几乎就是我们想要的,只是少了一个下划线,所以我们添加:
$ echo "${file_name%_*_*_*}_"
email_Tracking_export_history_
现在我们知道我们必须从字符串的开头删除什么并将其插入到 ${<em>word</em>#<em>pattern</em>}
扩展:
$ echo "${file_name#"${file_name%_*_*_*}_"}"
2018_08_15
或者我们将其分配给一个变量以供进一步使用:
string_name=${file_name#"${file_name%_*_*_*}_"}
└───┬───┘ │ └───┬───┘ └─┬──┘ │
outer word │ inner word └────────inner pattern
└───outer pattern────┘
第二个字符串类似。
% 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 个下划线的出现次数。然后将要提取的字符串部分反转回来。
使用(大部分)sed 和 BRE:
sed 's/.*_\([^_]*\(_[^_]*\)\{2\}\)$//' <<< "$file_name"
2018_08_15
使用 GNU sed 和 ERE:
sed -r 's/.*_([^_]*(_[^_]*){2})$//' <<< "$file_name"
2018_08_15
是否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.
我在 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
我怎样才能达到我想要的结果?
使用临时变量:
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"
如何在 bash 中使用正则表达式:
#!/bin/bash
# Extract substring from string after 3rd occurrence in reverse
function extract() {
if [[ "" =~ _([^_]+_[^_]+_[^_]+$) ]]; 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"
您可以一步完成,但有点复杂。设置文件名后
file_name='email_Tracking_export_history_2018_08_15'
我们得到包含所有内容的子字符串除了我们最后想要的内容:
$ echo "${file_name%_*_*_*}"
email_Tracking_export_history
这几乎就是我们想要的,只是少了一个下划线,所以我们添加:
$ echo "${file_name%_*_*_*}_"
email_Tracking_export_history_
现在我们知道我们必须从字符串的开头删除什么并将其插入到 ${<em>word</em>#<em>pattern</em>}
扩展:
$ echo "${file_name#"${file_name%_*_*_*}_"}"
2018_08_15
或者我们将其分配给一个变量以供进一步使用:
string_name=${file_name#"${file_name%_*_*_*}_"}
└───┬───┘ │ └───┬───┘ └─┬──┘ │
outer word │ inner word └────────inner pattern
└───outer pattern────┘
第二个字符串类似。
% 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 个下划线的出现次数。然后将要提取的字符串部分反转回来。
使用(大部分)sed 和 BRE:
sed 's/.*_\([^_]*\(_[^_]*\)\{2\}\)$//' <<< "$file_name"
2018_08_15
使用 GNU sed 和 ERE:
sed -r 's/.*_([^_]*(_[^_]*){2})$//' <<< "$file_name"
2018_08_15
是否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.