我有一个字符串,它看起来像这样:
"abcderwer 123123 10,200 asdfasdf iopjjop"
现在我想提取数字,遵循 xx,xxx 的方案,其中 x 是 0-9 之间的数字。例如 10,200。必须是五位数,并且必须包含“,”。
我该怎么做?
谢谢
grep
:$ echo "abcderwer 123123 10,200 asdfasdf iopjjop" | egrep -o '[0-9]{2},[0-9]{3}'
10,200
使用纯Bash:
pattern='([[:digit:]]{2},[[:digit:]]{3})'
[[ $string =~ $pattern ]]
echo "${BASH_REMATCH[1]}"
了解模式匹配和正则表达式。
链接:
如上所述,利用 grep 是一种使用模式匹配的方式。其他用途:echo 支持模式(globbing),find 支持正则表达式。
简单的模式匹配(glob patterns)已经内置于shell中。假设您在$*
中有字符串(也就是说,它们是脚本的命令行参数,或者您已经在其他地方使用了set
),请尝试以下操作:
for token; do
case $token in
[0-9][0-9],[0-9][0-9][0-9] ) echo "$token" ;;
esac
done
$@
。有所不同。 - Dennis Williamson$*
和$@
之间肯定存在差异;但我特别选择按其原始Bourne名称称呼包含argv
数组的变量,因为这是许多初学者级别的阐述所使用的名称;在这种情况下,当您希望将值拆分为以空格分隔的标记时,脚本会使用它。我同意,如果您必须直接引用位置参数,则几乎总是要使用"$@"
。 - tripleeeset -- 'abc def' ghi
和for arg in "$@"; do echo "$arg"; done
可以正确执行。但是,$*
或"$*"
通常不会得到正确的结果(只有在您想要展开参数时才会得到正确的结果)。继续重复错误的初学者级别的解释是没有意义的。 - Dennis Williamsonfor token; do
在这里都是正确的;有什么好争论的呢? - tripleee$ echo abcderwer 123123 10,200 asdfasdf iopjjop | sed -ne 's/^.*\([0-9,]\{6\}\).*$/\1/p'
10,200
< input tr -cd [0-9,\ ] | tr \ '\012' | grep '^..,...$'
(第一个tr除了逗号、空格和数字之外的所有内容。第二个tr将空格替换为换行符,将每个“数字”放在单独的一行上,grep丢弃除符合您条件的内容之外的所有内容。)