30

我只想匹配 Bash 脚本中的一些文本。我试过使用 sed 但我似乎无法让它只输出匹配而不是用某些东西替换它。

echo -E "TestT100String" | sed 's/[0-9]+/dontReplace/g'

哪个会输出TestTdontReplaceString

这不是我想要的,我希望它输出100.

理想情况下,它将所有匹配项放在一个数组中。

编辑:

文本输入以字符串形式出现:

newName()
{
 #Get input from function
 newNameTXT="$1"

 if [[ $newNameTXT ]]; then
 #Use code that im working on now, using the $newNameTXT string.

 fi
}
4

9 回答 9

49

您可以使用方括号[[ ]]测试运算符纯粹在 bash 中执行此操作,它将结果存储在一个名为 的数组中BASH_REMATCH

[[ "TestT100String" =~ ([0-9]+) ]] && echo "${BASH_REMATCH[1]}"
于 2009-12-14T01:59:10.600 回答
39
echo "TestT100String" | sed 's/[^0-9]*\([0-9]\+\).*/\1/'

echo "TestT100String" | grep -o  '[0-9]\+'

用于将结果放入数组的方法在某种程度上取决于实际数据的检索方式。您的问题中没有足够的信息能够很好地指导您。但是,这是一种方法:

index=0
while read -r line
do
    array[index++]=$(echo "$line" | grep -o  '[0-9]\+')
done < filename

这是另一种方式:

array=($(grep -o '[0-9]\+' filename))
于 2009-12-14T02:00:45.013 回答
29

重击。使用参数替换(没有外部进程和管道):

string="TestT100String"

echo ${string//[^[:digit:]]/}

删除所有非数字。

于 2009-12-16T17:33:25.677 回答
8

我知道这是一个老话题,但我通过同样的搜索找到了她,发现另一个很好的可能性是使用 grep 在字符串/变量上应用正则表达式:

# Simple
$(echo "TestT100String" | grep -Po "[0-9]{3}")
# More complex using lookaround
$(echo "TestT100String" | grep -Po "(?i)TestT\K[0-9]{3}(?=String)")

通过使用环视功能,可以扩展搜索表达式以获得更好的匹配。where(?i)表示搜索到的 Pattern 之前的 Pattern(lookahead), \K表示实际的搜索模式并(?=)包含搜索后的模式(lookbehind)。

https://www.regular-expressions.info/lookaround.html

给定的示例与 PCRE 正则表达式匹配TestT([0-9]{3})String

于 2019-04-12T10:58:51.673 回答
5

使用 grep。Sed 是一个编辑器。如果你只想匹配一个正则表达式,grep 绰绰有余。

于 2009-12-14T01:56:22.277 回答
1

使用 awk

linux$ echo -E "TestT100String" | awk '{gsub(/[^0-9]/,"")}1'
100
于 2009-12-14T02:38:11.053 回答
1

我不知道为什么没有人使用过expr:它既便携又容易。

newName()
{
 #Get input from function
 newNameTXT="$1"

 if num=`expr "$newNameTXT" : '[^0-9]*\([0-9]\+\)'`; then
  echo "contains $num"
 fi
}
于 2009-12-14T17:30:05.077 回答
0

好吧,带有 s/"pattern1"/"pattern2"/g 的 Sed 只是将所有模式 1 全局替换为模式 2。

除此之外, sed while 默认打印整行。我建议将指令传递给 cut 命令并尝试提取您想要的数字:

如果您只想使用 sed,请使用 TRE:

sed -n 's/.*\(0-9\)\(0-9\)\(0-9\).*/\1,\2,\3/g'.

我尝试执行上面的命令,所以只要确保语法是正确的。希望这有帮助。

于 2009-12-14T02:06:28.747 回答
-1

仅使用 bash shell

declare -a array
i=0
while read -r line
do
        case "$line" in
            *TestT*String* )
            while true
            do
                line=${line#*TestT}
                array[$i]=${line%%String*}
                line=${line#*String*}
                i=$((i+1))
                case "$line" in
                    *TestT*String* ) continue;;
                    *) break;;
                esac
            done
            esac
done <"file"
echo ${array[@]}
于 2009-12-14T02:44:48.747 回答