我有包含年号的目录名称。我想将它们拆分为年份数字之前的变量:
Holidays.uS.2019.bla.bla
Holidays.ca.old.2017.bla.bla
Holidays.2015.bla.bla.bla
Holidays.1.2.3.4.at.old.1999.bla.bla.bla.bla
年份并不总是在同一位置,但是,它总是有4位数字。
我一直都需要一年中的所有东西。
输入:
Holidays.ca.old.2017.bla.bla
Holidays.ca.old
set name Holidays.ca.old.2017.bla.bla
set numbers [regexp -all -inline {[0-9]+} $name]
我的代码输出的是年份数字,有时是其他错误的数字。
我在tcl中使用了它,对我来说效果很好:
set name_split [regsub {\.[0-9]{4}\y.*} $name ""]
bash脚本仍需要它,怎么使用?
这在bash中实际上不起作用:
name_split=$(echo $name | {\.[0-9]{4}\y.*}
答案 0 :(得分:2)
您可以使用sed
:
name="Holidays.uS.2019.bla.bla"
name_split="$(sed 's/\.[0-9]\{4\}\>.*//' <<< $name)"
echo $name_split
输出:Holidays.uS
,请参见online sed
demo。
注意:如果年份后必须有一个点,则可以匹配它而不是依靠单词边界:
name_split="$(sed 's/\.[0-9]\{4\}\..*//' <<< $name)"
^^
此处的sed
命令表示:
s/
-替代:\.
-一个点[0-9]\{4\}
-四位数\>
-尾随单词边界.*
-字符串的其余部分带有空字符串。
答案 1 :(得分:1)
为了安全起见,您可以在sed
命令中添加其他边界,并传递所需的字符:
#!/bin/bash
STRING="Holidays.1.2.3.4.at.old.1999.bla.bla.bla.bla"
MATCH="$(sed 's/\([A-z0-9\.]*\)\(\.[0-9]\{4\}.*\)$/\1/' <<< $STRING)"
echo $MATCH
Holidays.1.2.3.4.at.old
如果您不希望传递特殊字符,则this expression是安全的:
此图显示了它的工作原理
此摘要显示了表达式的性能,重复了100万次。
repeat = 1000000;
start = Date.now();
for (var i = repeat; i >= 0; i--) {
var string = "Holidays.1.2.3.4.at.old.1999.bla.bla.bla.bla";
var regex = /^([A-z0-9\.]*)(\.[0-9]{4}.*)/g;
var match = string.replace(regex, "$1");
}
end = Date.now() - start;
console.log("YAAAY! \"" + match + "\" is a match ");
console.log(end / 1000 + " is the runtime of " + repeat + " times benchmark test. ");
答案 2 :(得分:0)
以下是使用sed
的选项:
echo "Holidays.ca.old.2017.bla.bla" | sed 's/^\(.*\)\.[0-9]\{4\}.*$/\1/';
Holidays.ca.old
正则表达式简单地捕获所有内容,直到最后一个点,然后是四位数的年份,然后仅替换为所捕获的数量:
(.*) match and capture everything up until
\.[0-9]{4} a literal dot, followed by a four digit year
.* consume the remainder of the input
答案 3 :(得分:0)
这是不使用sed
的另一种方式:
#!/bin/bash
test_str="Holidays.ca.old.2017.bla.bla"
reg_ex='^(.*)\.([0-9]{4})' # Easy to read reg_ex vs sed reg_ex gibberish
if [[ $test_str =~ $reg_ex ]]
then
echo "1: ${BASH_REMATCH[1]}"
echo "2: ${BASH_REMATCH[2]}"
fi
输出:
1:Holidays.ca.old
2:2017年
答案 4 :(得分:0)
您可以使用parameter expansion来做到这一点:
$ str='Holidays.1.2.3.4.at.old.1999.bla.bla.bla.bla'
$ echo "${str%.[[:digit:]][[:digit:]][[:digit:]][[:digit:]]*}"
Holidays.1.2.3.4.at.old
这将删除一个句点,后跟四位数字,然后是字符串末尾的任何内容(*
通配符)。