在纯 bash 中使用 regexp 提取子字符串

我试图使用 bash 从字符串中提取时间,但是我很难找到它。

我的绳子是这样的:

US/Central - 10:26 PM (CST)

我要提取出 10:26的部分。

有人知道一种只使用 bash 而不使用 sed、 awk 等的方法吗?

比如,在 PHP 中,我会使用——虽然不是最好的方法,但是很管用——比如:

preg_match( ""(\d{2}\:\d{2}) PM \(CST\)"", "US/Central - 10:26 PM (CST)", $matches );

感谢任何帮助,即使答案使用 sed 或 awk

236463 次浏览

使用纯 :

$ cat file.txt
US/Central - 10:26 PM (CST)
$ while read a b time x; do [[ $b == - ]] && echo $time; done < file.txt

使用 bash regex 的另一种解决方案:

$ [[ "US/Central - 10:26 PM (CST)" =~ -[[:space:]]*([0-9]{2}:[0-9]{2}) ]] &&
echo ${BASH_REMATCH[1]}

另一种使用 grep和查看高级正则表达式的解决方案:

$ echo "US/Central - 10:26 PM (CST)" | grep -oP "\-\s+\K\d{2}:\d{2}"

使用 sed 的另一种解决方案:

$ echo "US/Central - 10:26 PM (CST)" |
sed 's/.*\- *\([0-9]\{2\}:[0-9]\{2\}\).*/\1/'

使用 perl 的另一种解决方案:

$ echo "US/Central - 10:26 PM (CST)" |
perl -lne 'print $& if /\-\s+\K\d{2}:\d{2}/'

最后一个是 awk:

$ echo "US/Central - 10:26 PM (CST)" |
awk '{for (i=0; i<=NF; i++){if ($i == "-"){print $(i+1);exit}}}'

快速、肮脏、不含正则表达式、低鲁棒性的剁剁技术

string="US/Central - 10:26 PM (CST)"
etime="${string% [AP]M*}"
etime="${etime#* - }"
    echo "US/Central - 10:26 PM (CST)" | sed -n "s/^.*-\s*\(\S*\).*$/\1/p"


-n      suppress printing
s       substitute
^.*     anything at the beginning
-       up until the dash
\s*     any space characters (any whitespace character)
\(      start capture group
\S*     any non-space characters
\)      end capture group
.*$     anything at the end
\1      substitute 1st capture group for everything on line
p       print it

如果你的绳子

foo="US/Central - 10:26 PM (CST)"

那么

echo "${foo}" | cut -d ' ' -f3

会完成任务的。

Foo = “ US/Central-10:26 PM (CST)”

echo ${foo} | date +%H:%M