在BASH脚本中返回正则表达式匹配,而不是替换它

时间:2009-12-14 01:53:06

标签: regex linux bash sed sh

我只想匹配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
} 

9 个答案:

答案 0 :(得分:32)

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

[[ "TestT100String" =~ ([0-9]+) ]] && echo "${BASH_REMATCH[1]}"

答案 1 :(得分:28)

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))

答案 2 :(得分:19)

Bash 。使用参数替换(无外部进程和管道):

string="TestT100String"

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

删除所有非数字。

答案 3 :(得分:6)

使用grep。 Sed是一名编辑。如果你只想匹配正则表达式,那么grep就足够了。

答案 4 :(得分:1)

使用awk

linux$ echo -E "TestT100String" | awk '{gsub(/[^0-9]/,"")}1'
100

答案 5 :(得分:1)

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

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

 if num=`expr "$newNameTXT" : '[^0-9]*\([0-9]\+\)'`; then
  echo "contains $num"
 fi
}

答案 6 :(得分:1)

我知道这是一个古老的话题,但是我还是跟着她一起搜索,发现使用grep在字符串/变量上使用正则表达式的另一种可能性很大:

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

使用环顾功能,可以扩展搜索表达式以实现更好的匹配。其中(?i)表示搜索的模式之前的模式(超前), \K表示实际的搜索模式,(?=)包含搜索后的模式(向后看)。

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

给定的示例与PCRE regex TestT([0-9]{3})String匹配

答案 7 :(得分:0)

嗯,带有s /“pattern1”/“pattern2”/ g的sed只是将所有pattern1s全局替换为模式2。

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

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

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

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

答案 8 :(得分:-2)

仅使用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[@]}