2013-04-16 6 views
22

Dato un nome host nel formato aaa0.bbb.ccc, voglio estrarre la prima sottostringa prima di ., ovvero, aaa0 in questo caso. Io uso seguente script awk a farlo,Utilizzare Awk per estrarre la sottostringa

echo aaa0.bbb.ccc | awk '{if (match($0, /\./)) {print substr($0, 0, RSTART - 1)}}' 

mentre lo script in esecuzione su una macchina A produce aaa0, in esecuzione sulla macchina B produce solo aaa senza 0 alla fine. Entrambi macchina funziona Ubuntu/Linaro, ma A corre versione di awk (gawk con la versione 3.1.8, mentre B con awk più anziani (mawk con la versione 1.2)

chiedo in generale, come scrivere uno script awk compatibile che esegue la stessa funzionalità ...

risposta

47

Hai voglia di impostare il separatore di campo come . utilizzando l'opzione -F e stampare il primo campo:

$ echo aaa0.bbb.ccc | awk -F'.' '{print $1}' 
aaa0 

stessa cosa, ma con taglio:

0.123.
$ echo aaa0.bbb.ccc | cut -d'.' -f1 
aaa0 

O con sed:

$ echo aaa0.bbb.ccc | sed 's/[.].*//' 
aaa0 

Anche grep:

$ echo aaa0.bbb.ccc | grep -o '^[^.]*' 
aaa0 
4

o semplicemente usare taglio:

echo aaa0.bbb.ccc | cut -d'.' -f1 
0

Non hanno bisogno awk per questo ...

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/.*/} 

opzioni più pesanti:

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 
+0

Downvoter, per favore fatemi sapere l'errore. Grazie :) – anishsane

1

che non è necessario alcun comando esterno a tutti, basta utilizzare il parametro di espansione in bash:

hostname=aaa0.bbb.ccc 
echo ${hostname%%.*} 
4

chiedo in generale, come scrivere un script awk compatibile che esegue la stessa funzionalità ...

A risolvere il problema nel tuo quesiton è facile. (controlla la risposta di altri).

Se si desidera scrivere uno script awk, quale portatile per eventuali implementazioni e versioni di awk (gawk/nawk/mawk ...) È davvero difficile, anche se con --posix (gawk)

ad esempio:

  • alcuni awk lavora su stringa in termini di personaggi, alcuni con i byte
  • alcuni supporti \x fuga, un po ' non
  • FS interprete funziona in modo diverso
  • parole chiave/parole riservate di restrizione abbreviazione
  • qualche operatore di restrizione per esempio **
  • anche lo stesso awk impl. (per esempio gawk), anche la versione 4.0 e la 3.x hanno delle differenze.
  • anche l'implementazione di alcune funzioni è diversa. (il tuo problema è un esempio, vedi sotto)

bene tutti i punti sopra sono solo parlati in generale. Tornando al tuo problema, il tuo problema è solo legato alla caratteristica fondamentale di awk. awk '{print $x}' la linea come quella funzionerà tutti gli awk.

Ci sono due motivi per cui la vostra linea awk si comporta in modo diverso su gawk e mawk:

  • tuo usato substr() funzione torto. questa è la causa principale. hai substr($0, 0, RSTART - 1) il 0 dovrebbe essere 1, non importa quale awk usi. awk array, string idx ecc sono basati su 1.

  • gawk e mawk implementati substr() in modo diverso.