Преобразование больших чисел HPUX, чтобы избежать таких чисел, как 2.13464e+07

Нет, здесь -строки взяты из zshв версии 2.0 в 1991 году (и/или из Unix-порта rc, их соответствующие авторы примерно в то время обменивались идеями, неясно, кто из них имел идею или включил ее в свою оболочку первым ).

Был добавлен в bash в 2.05b (2002 ), ksh93 в m+ (2002 ), mksh в R33 (2008 ),яш в 2.7 (2009 ).

ksh88 не получает никаких новых функций.

Вот документы (<<), сами исходят из оболочки Борна -конца 70-х.

read A B Cсчитывает одну логическую строку в переменные A, Bи Cочень особым образом (немного менее специальным образом со значением по умолчанию $IFS, которое содержит только IFS -белые -символы пробела¹ ), с обратной косой чертой, действующей как экранирующий и символ продолжения строки -, и то, что входит в C, также довольно сложно. Проделать то же самое без readбыло бы довольно сложно.

Во всяком случае, здесь <<<— это то же самое, что и <<, только синтаксические отличия.

read A B C << EOF
$var
EOF

точно такое же, как

read A B C <<< "$var" # note that some versions of bash need the quotes

во всех оболочках. В обоих случаях оболочка создает удаленный временный файл с содержимым и дополнительной новой строкой (, хотя некоторые оболочки вместо этого используют каналы ). Затем readсчитывает из нее одну логическую строку (, возможно, несколько физических строк, продолженных обратной косой чертой ), и заполняет переменные, используя свои сложные правила.

Он назначает только первые 3 слова (SPC/TAB с разделителями )из $varна $A, $Bи $C, если

  • $IFSпо-прежнему содержит значение по умолчанию
  • переменная не содержит обратной косой черты и новой строки
  • переменная содержит только 3 слова.

Для первых трех слов вы можете:

function split_into {
  typeset words IFS v i=0
  set -o noglob

  set -A words -- $1; shift
  for v do
    eval "$v=\${words[i]}"
    ((i += 1))
  done
}

split_into "$var" A B C
  
  

¹ Пробельные символы IFS , согласно POSIX, это символы, классифицируемые как [:space:]в локали и находящиеся в $IFS, хотя в ksh88 (, на котором основана спецификация POSIX )и в большинстве оболочек это по-прежнему ограничено SPC, TAB и NL. Единственной совместимой с POSIX оболочкой, которую я нашел в этом отношении, была yash. ksh93иbash(начиная с версии 5.0 )также включают другие пробелы (, такие как CR,FF, VT... ), но ограничены одиночными -байтами (, будьте осторожны в некоторых системах, таких как Solaris, которые включают неразрывное -пространство -, которое в некоторых локалях является одним байтом)

0
27.05.2020, 17:24
3 ответа

Почему бы вам просто не распечатать результат напрямую из awk? Второй awk там не нужен:

$ echo 21858717696 | awk '{printf "%.0f\n", $1/1024}'
21346404

Если я что-то не упустил, это точно так же, как ваша вторая команда:

$ echo 21858717696 | awk '{print $1/1024}' | bc -l | awk '{printf("%.0f\n", $1)}'
21346404

В моей системе Linux я могу воспроизвести это, только используя гораздо большее число и awk busybox:

$ echo 12321858717696000000000 |./awk '{print $1/1024}'
1.20331e+19

Но даже с busybox awk printfработает как положено:

$ echo 12321858717696000000000 |./awk '{printf "%.0f\n",$1/1024}'
12033065153999998976
0
18.03.2021, 23:32

У вас должен быть perl на HP -UX:

echo 21858717696|perl -ne 'printf "%.0f\n",$_/1024'
21346404
1
18.03.2021, 23:32

Поскольку вы уже используетеbc:

$ printf '%s/1024\n' 21858717696 | bc
21346404

или

$ echo '21858717696/1024' | bc
21346404

или любая другая комбинация, позволяющая bcвыполнить расчет за вас. Включите назначение scale, если вы хотите установить число десятичных знаков, которое вы хотите (равным нулю по умолчанию):

$ printf '%s\n' 'scale=4' '21858717696/1024' | bc
21346404.0000

Главное, чтобы bcвыполнял вычисления.

1
18.03.2021, 23:32

Теги

Похожие вопросы