Использовать 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, который выполняет ту же функциональность...
Ответы
Ответ 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