Подтвердить что ты не робот

Использовать Awk для извлечения подстроки

Учитывая имя хоста в формате aaa0.bbb.ccc, я хочу извлечь первую подстроку перед ., то есть aaa0 в этом случае. Я использую следующий awk script, чтобы сделать это,

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

Пока script работает на одном компьютере A создает aaa0, запуск на машине B производится только aaa, без 0 в конце. Обе машины работают Ubuntu/Linaro, но A запускает новую версию awk (gawk с версией 3.1.8, а B со старым awk (mawk с версией 1.2)

Я прошу в общем, как написать совместимый awk script, который выполняет ту же функциональность...

4b9b3361

Ответ 1

Вы просто хотите установить разделитель полей как . с помощью параметра -F и напечатать первое поле:

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

То же самое, но с помощью разреза:

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

Или с помощью sed:

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

Даже grep:

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

Ответ 2

Или просто используйте cut:

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

Ответ 3

В общем, я прошу написать совместимый awk script, который выполняет ту же функциональность...

Решить проблему в вашем quesiton легко. (проверьте ответ других).

Если вы хотите написать awk script, который переносится на любые awk-версии и версии (gawk/nawk/mawk...), это действительно сложно, даже если с -posix (gawk)

например:

  • некоторые awk работают с строкой в ​​терминах символов, некоторые с байтами
  • некоторые поддерживают \x escape, некоторые не
  • FS интерпретатор работает по-другому.
  • ключевые слова/зарезервированные слова сокращение сокращение
  • некоторое ограничение оператора, например. **
  • даже тот же самый awk impl. (например, gawk), версии 4.0 и 3.x тоже имеют разницу.
  • реализация некоторых функций также различна. (ваша проблема - один пример, см. ниже).

Ну, все вышеперечисленные моменты просто говорят в целом. Вернемся к вашей проблеме, ваша проблема связана только с фундаментальной особенностью awk. awk '{print $x}' строка вроде этого будет работать со всеми awks.

Есть две причины, по которым ваша строка awk ведет себя по-разному в gawk и mawk:

  • ваша используемая функция substr() ошибочна. это основная причина. у вас substr($0, 0, RSTART - 1) 0 должно быть 1, независимо от того, какой awk вы используете. массив awk, строка idx и т.д. основаны на 1.

  • gawk и mawk реализованы substr() по-разному.

Ответ 4

Вам вообще не нужна внешняя команда, просто используйте расширение параметра в bash:

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

Ответ 5

Вам не нужно awk для этого...

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

Более тяжелые варианты:

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