匹配bash脚本中的确切单词,从字符串中提取数字

时间:2014-06-09 23:04:29

标签: bash shell text-parsing

我试图创建一个非常简单的bash脚本,它将根据输入命令打开新的链接

用例#1

$ ./myscript longname55445

应该使用数字 55445 ,然后将其分配给一个变量,该变量稍后将用于根据给定的数字打开新链接。

用例#2

$ ./myscript l55445

它应该通过取数字然后打开相同的链接来完成与上面完全相同的事情。

用例#3

$ ./myscript 55445

如果没有给出前缀,那么我们只需打开与回退相同的链接。

到目前为止,这就是我所拥有的

#!/bin/sh

BASE_URL=http://api.domain.com
input=$1
command=${input:0:1}

if [ "$command" == "longname" ]; then
  number=${input:1:${#input}}
  url="$BASE_URL?id="$number
  open $url
elseif [ "$command" == "l" ]; then
   number=${input:1:${#input}}
  url="$BASE_URL?id="$number
  open $url
else
  number=${input:1:${#input}}
  url="$BASE_URL?id="$number
  open $url
fi

但这总是会回到那里的elseif

我现在正在使用zsh

5 个答案:

答案 0 :(得分:3)

input=$1
command=${input:0:1}

command设置为第一个参数的第一个字符。一个字符串不可能等于八个字符的字符串(“longname”),因此if条件必须始终失败。

此外,您的elseifelse条款都设置了

number=${input:1:${#input}}

你可以更简单地写成

number=${input:1}

但是在这两种情况下,你都放弃了input的第一个角色。大概在else的情况下,你想要整个第一个参数。

答案 1 :(得分:2)

查看此构造是否有助于您的目的:

#!/bin/bash
name="longname55445"
echo "${name##*[A-Za-z]}"

这假设一个字母与数字相邻。

以下是 NOT 另一种写同样的方法,因为它是错误的。 请注意以下mklement0的评论,他注意到了这一点。 Mea culpa。

echo "${name##*[:letter:]}"     

答案 2 :(得分:1)

您有command=${input:0:1}

需要第一个字符,并将其与"longname"进行比较,当然它会失败,然后转到elseif。

关键问题是检查输入是以l还是longname还是nothing开头。如果在3个案例中的一个案例中,请使用尾随数字。

一个grep行可以做到这一点,你可以在input上grep并获取返回的文本:

kent$  grep -Po '(?<=longname|l|^)\d+' <<<"l234"
234

kent$  grep -Po '(?<=longname|l|^)\d+' <<<"longname234"
234

kent$  grep -Po '(?<=longname|l|^)\d+' <<<"234"        
234

kent$  grep -Po '(?<=longname|l|^)\d+' <<<"foobar234"
<we got nothing>

答案 3 :(得分:1)

您可以在bash中使用正则表达式匹配。

[[ $1 =~ [0-9]+ ]] && number=$BASH_REMATCH

您还可以在zsh中使用正则表达式匹配。

[[ $1 =~ [0-9]+ ]] && number=$MATCH

答案 4 :(得分:0)

基于OP在评论中的以下澄清,

  

我只是在寻找输入中给出的数字[...]。

解决方案可简化如下:

#!/bin/bash

BASE_URL='http://api.domain.com'

  # Strip all non-digits from the 1st argument to get the desired number.
number=$(tr -dC '[:digit:]' <<<"$1")

open "$BASE_URL?id=$number"

请注意使用 bash shebang,因为使用了'bashism'<<<(可以很容易地以符合POSIX的方式重新设置)。

同样,OP的原始代码也应该使用bash shebang,因为使用了非POSIX子字符串提取语法。

但是,通过使用open来打开网址,OP似乎位于OSX上,其中sh基本上是bash(尽管调用为sh 更改行为),因此仍然可以 。但一般来说,明确所需的shell更安全。