bash buscar Use Awk para extraer la subcadena




cut linux (4)

Solo desea configurar el separador de campo como . usando la opción -F e imprime el primer campo:

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

Lo mismo pero con corte:

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

O con sed :

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

Incluso grep :

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

Dado un nombre de host en formato de aaa0.bbb.ccc , quiero extraer la primera subcadena anterior . , es decir, aaa0 en este caso. Uso siguiendo el script awk para hacerlo,

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

Mientras que la secuencia de comandos que se ejecuta en una máquina A produce aaa0 , la ejecución en la máquina B produce solo aaa , sin 0 al final. Ambas máquinas ejecutan Ubuntu/Linaro , pero A ejecuta una versión más nueva de awk (gawk con la versión 3.1.8, mientras que B con awk más antiguo (mawk con la versión 1.2)

En general, estoy preguntando cómo escribir un script awk compatible que realice la misma funcionalidad ...


Answer #1

No necesitas awk para esto ...

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

Opciones más pesadas:

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 

Answer #2

No necesitas ningún comando externo, solo usa la expansión de parámetros en bash:

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

Answer #3

En general, estoy preguntando cómo escribir un script awk compatible que realice la misma funcionalidad ...

Para resolver el problema en su pregunta es fácil. (verifique la respuesta de los demás).

Si quieres escribir un script awk, que es portable para cualquier implementación y versión de awk (gawk / nawk / mawk ...) es realmente difícil, incluso con --posix (gawk)

por ejemplo:

  • algunos awk funcionan en cadena en términos de caracteres, algunos con bytes
  • algunos soportes \x escape, algunos no
  • FS intérprete de FS funciona de manera diferente
  • palabras clave / palabras reservadas restricción de abreviatura
  • alguna restricción de operador ej. **
  • incluso el mismo awk impl. (Gawk, por ejemplo), la versión 4.0 y 3.x también tienen una diferencia.
  • la implementación de ciertas funciones también son diferentes. (tu problema es un ejemplo, mira abajo)

Bueno, todos los puntos anteriores solo se hablan en general. Volviendo a su problema, su problema solo está relacionado con la característica fundamental de awk. awk '{print $x}' la línea así funcionará todos los awks.

Hay dos razones por las que su línea awk se comporta de manera diferente en gawk y mawk:

  • su substr() usado funciona incorrectamente. esta es la causa principal. tiene substr($0, 0, RSTART - 1) el 0 debe ser 1 , no importa qué awk use. awk array, string idx etc. están basados ​​en 1.

  • gawk y mawk implementaron substr() diferente.





awk