Почему zsh printf не поддерживает восьмеричное представление?

С помощью GNU awk для strtonum (), если вы вводите шестнадцатеричные числа:

$ awk '{printf "%04X\n", strtonum("0x"$0)}' file
0030
0001
0508
A0EA
A0EB
A0EC
A0ED

С GNU awk независимо от того, является ли ваш ввод шестнадцатеричным или нет:

$ awk '{print gensub(/ /,0,"g",sprintf("%4s",$0))}' file
0030
0001
0508
A0EA
A0EB
A0EC
A0ED

С любым awk независимо от того, является ли ваш ввод шестнадцатеричным или нет:

$ awk '{v=sprintf("%4s",$0); gsub(/ /,0,v); print v}' file
0030
0001
0508
A0EA
A0EB
A0EC

или даже:

$ awk '{$0=sprintf("%4s",$0); gsub(/ /,0)} 1' file
0030
0001
0508
A0EA
A0EB
A0EC
A0ED
1
11.09.2021, 09:48
1 ответ

Почему zsh не поддерживает восьмеричное представление?

Часть почему основана на мнении. Мнение того, кто решил заставить его работать таким образом.

Как как более техническое:

Как

В printf передаются строковые аргументы. Чтобы преобразовать строку в число, требуется некоторый класс интерпретации/преобразования. Обычно преобразование выполняется по правилам Арифметического вычисления .

В разных оболочках арифметическая оценка может различаться.

$ for mysh in dash sh mksh ksh bash zsh ; do
      printf '%10s:' "$mysh"; 
      $mysh -c 'printf "%d " 024; echo $((024))';
  done; 
  echo

      dash:20 20
        sh:20 20
      mksh:20 24
       ksh:24 20
      bash:20 20
       zsh:24 24

Обратите внимание на разницу между mksh и ksh, где printfделает одно, а $((... ))— противоположное.

В zshарифметическая оценка не распознает начальный 0как восьмеричный маркер. Но это возможно, если установлена ​​опция OCTAL_ZEROES. И он устанавливается по умолчанию в эмуляции zsh sh.

Это делает zshособенным (, отличным от большинства других оболочек )в том смысле, что как в printf, так и в $((...))целое число, начинающееся с нуля, не распознается как восьмеричное.

Мне нравится идея избегать особых случаев для восьмеричных чисел, когда ноль появляется в дне или месяце даты, но мне также нравится идея, что код должен быть переносимым, настолько переносимым, насколько это возможно.

Возможно, решение всех оболочек, распознающих только 0o123целые числа как восьмеричные, может решить проблему.

0
12.09.2021, 23:40

Теги

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