J'ai une chaîne, par exemple
"Icecream123 AirplaneBCD CompanyTL1 ComputerYU1"
Disons que je sais que ma chaîne contiendra à coup sûr la sous-chaîne IceCream mais je ne sais pas ce qui la suit.
Ce pourrait être 123 comme dans mon exemple ou ce pourrait être quelque chose de différent.
Bien que je puisse utiliser grep pour détecter si la sous-chaîne "Icecream" existe dans ma chaîne avec la commande suivante
echo $string | grep -oF 'Icecream';
Qui va imprimer
Icecream
Je veux avec une commande pour l'obtenir pour imprimer la sous-chaîne entière, qui dans mon exemple est
Icecream123
Bien sûr, ce qui suit Icecream est aléatoire et n'est pas connu à l'avance, donc je ne peux pas simplement faire
$SUBSTRING=$(echo $string | grep -oF 'Icecream')
$SUBSTRINGTRAIL=123
echo $SUBSTRING$SUBSTRINGTRAIL
Si votre grep
prend en charge les expressions régulières compatibles Perl, vous pouvez faire correspondre sans avidité jusqu'à la prochaine limite de Word:
echo "$string" | grep -oP 'Icecream.*?\b'
Sinon, faites correspondre la séquence la plus longue de caractères non vides:
echo "$string" | grep -o 'Icecream[^[:blank:]]*'
Ou conservez tout dans le Shell et supprimez la séquence de caractères la plus longue commençant par un espace:
echo "${string%% *}"
Utilisation d'un grep
qui connaît -o
:
$ printf '%s\n' "$string" | grep -o '\<Icecream[^[:blank:]]*'
Icecream123
Le motif \<Icecream[^[:blank:]]*
correspond à la chaîne Icecream
(où I
est précédé d'un caractère non Word ou du début de la ligne) suivi de zéro ou plusieurs espaces non (pas d'espaces ni de tabulations) .
Utilisation de awk
:
$ printf '%s\n' "$string" | awk -v RS=' ' '/^Icecream/'
Icecream123
Le programme awk
divise la chaîne en enregistrements séparés par des espaces et teste chacun d'eux. Il affichera ceux qui commencent par la chaîne Icecream
.
En utilisant mawk
ou GNU awk
, vous pouvez également utiliser
printf '%s\n' "$string" | awk -v RS='[[:blank:]]' '/^Icecream/'
car ils interprètent RS
comme une expression régulière si elle contient plusieurs caractères.
Avec sed
, de la même manière qu'avec grep
:
$ printf '%s\n' "$string" | sed 's/.*\(\<Icecream[^[:blank:]]*\).*/\1/'
Icecream123
En utilisant /bin/sh
:
set -- Icecream123 AirplaneBCD CompanyTL1 ComputerYU1
for string; do
case $string in
Icecream*)
printf '%s\n' "$string"
break
esac
done
Perl (avec un peu d'aide de tr
):
$ printf '%s\n' "$string" | tr ' ' '\n' | Perl -ne '/Icecream\S*/ && print'
Icecream123
ou juste
$ printf '%s\n' "$string" | Perl -ne '/(Icecream\S*)/ && print $1, "\n"'
Icecream123
Depuis que vous avez marqué bash:
[[ $string =~ (Icecream[^ ]*) ]] && result=${BASH_REMATCH[1]}
Plus généralement, pour un terme de recherche dans $search
:
[[ $string =~ ($search[^ ]*) ]] && result=${BASH_REMATCH[1]}
... ou avec extension des paramètres:
# remove any leading text up to -and through- the search text:
x=${string##*$search}
# remove any trailing space onwards
result=$search${x%% *}
Par exemple, si vous utilisez GNU grep
:
$ echo "Icecream123 AirplaneBCD CompanyTL1 ComputerYU1" | grep -oP '\bIcecream.*?(\s|$)' --color
Il utilise PCRE
.
Un peu plus simple peut-être, d'autant plus que vous dites que votre version de grep ne prend pas en charge l'expression régulière Perl:
$ echo $string | tr ' ' '\n' | grep 'Icecream' Icecream123
tr
divise la chaîne en lignes en remplaçant tous les espaces par des retours à la ligne. Ensuite, vous pouvez facilement utiliser grep
.
Vous pouvez également écrire ce qui suit pour obtenir uniquement ce qui suit le mot que vous recherchez:
$ echo $string | tr ' ' '\n' | sed -n 's/Icecream//p' 123