Как отделить число и единицу от переменной при использовании awk - PullRequest
0 голосов
/ 18 мая 2018

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

~$ echo 139506MB | awk '{
   ex = index("KMGTPEZY", substr($1, length($1)));
   val = substr($1, 0, length($1) - 2);
   print ex " " val
   }'
0 139506

Я знаю, что единичная часть всегда состоит из 2 символов, но по какой-то причине ex всегда возвращает 0 вместо MB, как я и надеялся.

Вопрос

Есть идеи, почему ex не содержит единицы?

Ответы [ 5 ]

0 голосов
/ 18 мая 2018

Ваш substr() вызов substr($1, length($1)), который вернет только последний символ $1 (B).Этот символ не является частью строки KMGTPEZY.

$ echo '139506MB' | awk '{ n=$1+0; sub(n,"",$1); print $1,n }'
MB 139506

При этом используется тот факт, что преобразование строки в число отбрасывает все, начиная с первой нецифровой цифры.Это позволяет нам сохранить число в n, используя $1+0 (принудительно интерпретируя первое поле как число).Затем мы удаляем номер из исходной строки, используя sub().Затем будет напечатан номер и оставшийся текст.

0 голосов
/ 18 мая 2018

Логика в вашей функции index() неверна, символ, который вы извлекли, не является частью определенной вами строки.Отсюда возвращаемое значение 0, которое вы видите.

Для подхода регулярных выражений, использующего GNU Awk для хранения захваченных групп в массиве.С функцией match() вы можете сделать, как показано ниже.Захваченные группы сохраняются в массив (ar), из которого вы можете получить доступ к элементам 1 и 2.

echo 139506MB | gawk 'match($0, /([[:digit:]]+)([[:alpha:]]+)/, ary) {print ary[1] ary[2]}'
0 голосов
/ 18 мая 2018

Использование GNU awk и split s seps для злоупотребления .B в качестве разделителя для отделения числа и единицы от переменной при использовании (GNU) awk:

$ echo 139506MB  | awk '{split($1,a,/.B/,seps);print seps[1],a[1]}'
MB 139506

Кроме того, в отношении вашего кода: вы (пытаетесь) установить index из M в строке KMGTPEZY, поэтому я предполагаю, что вы ищете ex==2.Исправив substr, как показано ниже:

$ echo 139506MB | awk '{
   ex = index("KMGTPEZY", substr($1, length($1)-1,1));    # from substr($1, length($1))
   # ex = substr($1, length($1)-1,1);                     # uncomment for the unit
   val = substr($1, 0, length($1) - 2);
   print ex " " val
   }'
2 139506

Возможно, вам следует обновить OP с ожидаемым выводом.

0 голосов
/ 18 мая 2018

После awk может помочь вам тоже.

str="139506MB"
echo "$str" | awk '
match($0,/[0-9]+/){
  val=substr($0,RSTART+RLENGTH);
  if(val ~ /[a-zA-Z]+/){
     print substr($0,RSTART,RLENGTH),val}
}'
0 голосов
/ 18 мая 2018

Первая проблема здесь:

substr($1, length($1))

Вы получаете последний символ строки, который является "B".В «KMGTPEZY» нет буквы «B», поэтому index возвращает 0.

Я не думаю, что вам вообще нужно использовать index.Для использования substr:

ex = substr($1, length($1) - 1);
val = substr($1, 0, length($1) - 2);

Тестирование:

$ awk '{ print substr($1, length($1) - 1), substr($1, 0, length($0) - 2) }' <<< '139506MB'
MB 139506
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...