Étant donné un nom d'hôte au format aaa0.bbb.ccc
, Je veux extraire la première sous-chaîne avant .
, C'est, aaa0
dans ce cas. J'utilise le script awk suivant pour le faire,
echo aaa0.bbb.ccc | awk '{if (match($0, /\./)) {print substr($0, 0, RSTART - 1)}}'
Tandis que le script exécuté sur une machine, A
produit aaa0
, en cours d'exécution sur la machine B
ne produit que aaa
, sans 0
à la fin. Les deux machines fonctionnent Ubuntu/Linaro
, mais A
exécute une version plus récente de awk (gawk avec la version 3.1.8 alors que B
avec un ancien awk (mawk avec la version 1.2)
Je demande en général, comment écrire un script awk compatible qui exécute la même fonctionnalité ...
Vous voulez juste définir le séparateur de champs comme .
en utilisant le -F
option et imprimer le premier champ:
$ echo aaa0.bbb.ccc | awk -F'.' '{print $1}'
aaa0
Même chose mais en utilisant cut:
$ echo aaa0.bbb.ccc | cut -d'.' -f1
aaa0
Ou avec sed
:
$ echo aaa0.bbb.ccc | sed 's/[.].*//'
aaa0
Même grep
:
$ echo aaa0.bbb.ccc | grep -o '^[^.]*'
aaa0
Je demande en général, comment écrire un script awk compatible qui exécute la même fonctionnalité ...
Résoudre le problème dans votre question est facile. (vérifiez la réponse des autres).
Si vous voulez écrire un script awk qui soit portable pour toutes les implémentations et versions de awk (gawk/nawk/mawk ...), c'est vraiment difficile, même avec --posix (gawk)
par exemple:
\x
, d'autres nonFS
l'interprète fonctionne différemmentbien tous les points ci-dessus sont juste parlé en général. De retour à votre problème, votre problème est uniquement lié à la fonctionnalité fondamentale de awk. awk '{print $x}'
La ligne comme ça fonctionnera tous les awks.
Il y a deux raisons pour lesquelles votre ligne awk se comporte différemment sur gawk et mawk:
votre fonction substr()
utilisée à tort. c'est la cause principale. vous avez substr($0, 0, RSTART - 1)
le 0
devrait être 1
, quel que soit votre awk. Le tableau awk, la chaîne idx, etc. sont basés sur 1.
gawk et mawk ont implémenté substr()
différemment.
Ou utilisez simplement couper:
echo aaa0.bbb.ccc | cut -d'.' -f1
Vous n'avez besoin d'aucune commande externe, utilisez simplement Parameter Expansion dans bash:
hostname=aaa0.bbb.ccc
echo ${hostname%%.*}
Vous n'avez pas besoin de awk pour ça ...
echo aaa0.bbb.ccc | cut -d. -f1
cut -d. -f1 <<< aaa0.bbb.ccc
echo aaa0.bbb.ccc | { IFS=. read a _ ; echo $a ; }
{ IFS=. read a _ ; echo $a ; } <<< aaa0.bbb.ccc
x=aaa0.bbb.ccc; echo ${x/.*/}
Options plus lourdes:
sed:
echo aaa0.bbb.ccc | sed 's/\..*//'
sed 's/\..*//' <<< aaa0.bbb.ccc
awk:
echo aaa0.bbb.ccc | awk -F. '{print $1}'
awk -F. '{print $1}' <<< aaa0.bbb.ccc