2013-04-16 14 views
22

Bei einem Hostnamen im Format aaa0.bbb.ccc, ich möchte die erste Teilzeichenfolge vor ., also aaa0 in diesem Fall extrahieren. Ich folgenden awk-Skript verwenden, dies zu tun,Verwenden Sie Awk, um Teilzeichenfolge zu extrahieren

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

Während das Skript auf einer Maschine läuft A produziert aaa0, läuft auf der Maschine B produziert nur aaa, ohne 0 am Ende. Beide Maschine läuft Ubuntu/Linaro, aber A läuft neuere Version von awk (gaffen mit Version 3.1.8 während B mit älteren awk (mawk mit Version 1.2)

ich im Allgemeinen bin zu fragen, wie ein kompatibles awk-Skript zu schreiben, das führt gleiche Funktionalität ...

Antwort

47

Sie haben soeben das Feldtrenn als . mit der -F Option festlegen möchten, und drucken Sie das erste Feld:

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

gleiche, aber mit cut:

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

Oder mit sed:

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

Auch grep:

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

Oder gerade Schnitt verwenden:

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

Sie brauchen nicht awk für dieses ...

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

Schwerere Optionen:

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, bitte lassen Sie mich den Fehler wissen. Vielen Dank :) – anishsane

1

Sie benötigen keine externen Befehl überhaupt, verwenden Sie einfach Parameter Expansion in bash:

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

ich im Allgemeinen bin zu fragen, wie man schreibt ein kompatibles awk-Skript, das die gleiche Funktionalität ausführt ...

An Lösen Sie das Problem in Ihrer Frage ist einfach. (überprüfen Sie die Antwort anderer).

Wenn Sie ein awk-Skript schreiben möchten, das zu allen awk-Implementierungen und Versionen portierbar ist (gawk/nawk/mawk ...) Ist es wirklich schwer, auch wenn mit --posix (gawk)

zum Beispiel:

  • einige awk in Bezug auf die Zeichen auf Zeichenfolge funktioniert, \x Flucht einige mit Bytes
  • einigen Trägern, einige
  • nicht
  • FS Interpreter funktioniert anders
  • Schlüsselwörter/reservierte Wörter Abkürzung Einschränkung
  • einige Betreiber Einschränkung zB **
  • sogar gleiche awk impl. (gawk zum Beispiel), die Version 4.0 und 3.x haben auch einen Unterschied.
  • die Implementierung bestimmter Funktionen sind auch unterschiedlich. (Ihr Problem ist ein Beispiel, siehe unten)

gut alle oben genannten Punkte werden nur im Allgemeinen gesprochen. Zurück zu Ihrem Problem, Ihr Problem bezieht sich nur auf das grundlegende Merkmal von awk. awk '{print $x}' die Linie wie das funktioniert alle Awks.

Es gibt zwei Gründe, warum Ihre awk Linie anders auf gaffen und mawk verhält:

  • Ihre gebrauchten substr() Funktion falsch. Dies ist die Hauptursache. Sie haben substr($0, 0, RSTART - 1) die 0 sollte 1 sein, egal welche awk verwenden Sie. awk array, string idx usw. sind 1-basiert.

  • gawk und mawk implementiert substr() anders.

Verwandte Themen