例如,我有一个字符串
"Icecream123 AirplaneBCD CompanyTL1 ComputerYU1"
假设我知道我的字符串肯定会包含子字符串 IceCream,但我不知道它后面是什么。
在我的示例中,它可能是 123,也可能是其他值。
虽然我可以使用 grep 通过以下命令来检测字符串中是否存在“Icecream”子字符串
echo $string | grep -oF 'Icecream';
哪个将打印
Icecream
我想用一个命令让它打印整个子字符串,在我的示例中是
Icecream123
当然,接下来的冰淇淋是随机的,并且事先不知道,所以我不能只是这样做
$SUBSTRING=$(echo $string | grep -oF 'Icecream')
$SUBSTRINGTRAIL=123
echo $SUBSTRING$SUBSTRINGTRAIL
答案1
如果您grep
支持 perl 兼容的正则表达式,您可以非贪婪地匹配到下一个单词边界:
echo "$string" | grep -oP 'Icecream.*?\b'
否则,匹配最长的非空白字符序列:
echo "$string" | grep -o 'Icecream[^[:blank:]]*'
或者将所有内容保留在 shell 中并删除以空格开头的最长尾随字符序列:
echo "${string%% *}"
答案2
由于您标记了 bash:
[[ $string =~ (Icecream[^ ]*) ]] && result=${BASH_REMATCH[1]}
更一般地说,对于以下位置的搜索词$search
:
[[ $string =~ ($search[^ ]*) ]] && result=${BASH_REMATCH[1]}
...或使用参数扩展:
# remove any leading text up to -and through- the search text:
x=${string##*$search}
# remove any trailing space onwards
result=$search${x%% *}
答案3
使用grep
知道的-o
:
$ printf '%s\n' "$string" | grep -o '\<Icecream[^[:blank:]]*'
Icecream123
该模式\<Icecream[^[:blank:]]*
匹配字符串Icecream
(其中I
前面是非单词字符或行的开头),后跟零个或多个非空格(不是空格或制表符)。
使用awk
:
$ printf '%s\n' "$string" | awk -v RS=' ' '/^Icecream/'
Icecream123
该awk
程序将字符串划分为空格分隔的记录,并测试每个记录。它将打印以 string 开头的内容Icecream
。
使用mawk
或 GNU awk
,您也可以使用
printf '%s\n' "$string" | awk -v RS='[[:blank:]]' '/^Icecream/'
因为RS
如果它包含多个字符,它们就会解释为正则表达式。
与sed
,以与 类似的方式grep
:
$ printf '%s\n' "$string" | sed 's/.*\(\<Icecream[^[:blank:]]*\).*/\1/'
Icecream123
使用/bin/sh
:
set -- Icecream123 AirplaneBCD CompanyTL1 ComputerYU1
for string; do
case $string in
Icecream*)
printf '%s\n' "$string"
break
esac
done
Perl(在 的帮助下tr
):
$ printf '%s\n' "$string" | tr ' ' '\n' | perl -ne '/Icecream\S*/ && print'
Icecream123
要不就
$ printf '%s\n' "$string" | perl -ne '/(Icecream\S*)/ && print $1, "\n"'
Icecream123
答案4
也许更简单一点,特别是因为你说你的 grep 版本不支持 perl 正则表达式:
$ echo $string | tr ' ' '\n' | grep 'Icecream' Icecream123
tr
通过用换行符替换所有空格,将字符串拆分为行。然后就可以grep
轻松使用了。
您还可以编写以下内容以仅获取您要查找的单词后面的内容:
$ echo $string | tr ' ' '\n' | sed -n 's/Icecream//p' 123