J'ai une chaîne comme celle-ci:
/var/cpanel/users/joebloggs:DNS9=domain.com
J'ai besoin d'extraire le nom d'utilisateur (joebloggs
) de cette chaîne et de le stocker dans une variable.
Le format de la chaîne sera toujours le même à l'exception de joebloggs
et domain.com
donc je pense que la chaîne peut être divisée deux fois à l'aide de cut
?
La première division serait scindée par :
et nous stockerions la première partie dans une variable à transmettre à la deuxième fonction de scission.
La seconde scission serait scindée par /
et stockerait le dernier mot (joebloggs
) dans une variable
Je sais comment faire cela en php en utilisant des tableaux et des scissions, mais je suis un peu perdu en bash.
Pour extraire joebloggs
de cette chaîne dans bash en utilisant l’extension de paramètre sans aucun processus supplémentaire ...
MYVAR="/var/cpanel/users/joebloggs:DNS9=domain.com"
NAME=${MYVAR%:*} # retain the part before the colon
NAME=${NAME##*/} # retain the part after the last slash
echo $NAME
Ne dépend pas de joebloggs
être à une profondeur particulière du chemin.
Résumé
Un aperçu de quelques modes d’expansion des paramètres, pour référence ...
${MYVAR#pattern} # delete shortest match of pattern from the beginning
${MYVAR##pattern} # delete longest match of pattern from the beginning
${MYVAR%pattern} # delete shortest match of pattern from the end
${MYVAR%%pattern} # delete longest match of pattern from the end
Donc, #
signifie une correspondance depuis le début (pensez à une ligne de commentaire) et %
signifie depuis la fin. Une instance signifie le plus court et deux instances signifie le plus long.
Vous pouvez obtenir des sous-chaînes basées sur la position en utilisant des nombres:
${MYVAR:3} # Remove the first three chars (leaving 4..end)
${MYVAR::3} # Return the first three characters
${MYVAR:3:5} # The next five characters after removing the first 3 (chars 4-9)
Vous pouvez également remplacer des chaînes ou des modèles particuliers en utilisant:
${MYVAR/search/replace}
Le pattern
est dans le même format que la correspondance de nom de fichier, donc *
(tous les caractères) est commun, souvent suivi d'un symbole particulier comme /
ou .
Exemples:
Étant donné une variable comme
MYVAR="users/joebloggs/domain.com"
Supprimez le chemin en laissant le nom de fichier (tous les caractères jusqu'à la barre oblique):
echo ${MYVAR##*/}
domain.com
Supprimez le nom du fichier en laissant le chemin (supprimez la correspondance la plus courte après le dernier /
):
echo ${MYVAR%/*}
users/joebloggs
Obtenir uniquement l'extension de fichier (tout supprimer avant la dernière période):
echo ${MYVAR##*.}
com
REMARQUE: Pour effectuer deux opérations, vous ne pouvez pas les combiner, mais vous devez les affecter à une variable intermédiaire. Donc, pour obtenir le nom du fichier sans chemin ni extension:
NAME=${MYVAR##*/} # remove part before last slash
echo ${NAME%.*} # from the new var remove the part after the last period
domain
Définissez une fonction comme celle-ci:
getUserName() {
echo $1 | cut -d : -f 1 | xargs basename
}
Et passez la chaîne en tant que paramètre:
userName=$(getUserName "/var/cpanel/users/joebloggs:DNS9=domain.com")
echo $userName
Qu'en est-il de Sed? Cela fonctionnera en une seule commande:
sed 's#.*/\([^:]*\).*#\1#' <<<$string
#
sont utilisés pour les diviseurs de regex au lieu de /
car la chaîne contient /
..*/
saisit la chaîne jusqu'à la dernière barre oblique inverse.\( .. \)
marque un groupe de capture. C'est \([^:]*\)
. [^:]
dit n'importe quel caractère _ sauf un deux-points, et le *
signifie zéro ou plus..*
signifie le reste de la ligne.\1
signifie remplacer par ce qui a été trouvé dans le premier (et le seul) groupe de capture. C'est le nom.Voici la ventilation correspondant à la chaîne avec l'expression régulière:
/var/cpanel/users/ joebloggs :DNS9=domain.com joebloggs
sed 's#.*/ \([^:]*\) .* #\1 #'
Utiliser un seul sed
echo "/var/cpanel/users/joebloggs:DNS9=domain.com" | sed 's/.*\/\(.*\):.*/\1/'
En utilisant un seul Awk:
... | awk -F '[/:]' '{print $5}'
C'est-à-dire qu'en utilisant comme séparateur de champ soit /
ou :
, le nom d'utilisateur est toujours dans le champ 5.
Pour le stocker dans une variable:
username=$(... | awk -F '[/:]' '{print $5}')
Une implémentation plus flexible avec sed
qui n'exige pas que le nom d'utilisateur soit dans le champ 5:
... | sed -e s/:.*// -e s?.*/??
En d’autres termes, supprimez tout ce qui se trouve dans :
et au-delà, puis supprimez tout jusqu’au dernier /
. sed
est probablement aussi plus rapide que awk
, donc cette alternative est définitivement meilleure.