2012-01-13 2 views
5

У меня очень странная проблема с/bin/bash и скриптом, который использует printf для форматирования строки./bin/bash printf не работает с другим LANG, чем C

Мой сценарий выглядит следующим образом

rt=$(printf "%.3f" 13.234324245) 

с той разницей, что я вычислить число 13.23 ... выше. Когда я использую/usr/bin/zsh, это отлично работает! Even/bin/sh может это сделать (но он не может делать что-то ...) Самая большая проблема ist, что/bin/bash, похоже, не понимает printf или имеет другой способ форматирования, когда я не использую LANG=C.

My LANG переменная установлена ​​в de_AT.UTF-8, а затем я получаю эту ошибку:

/path/to/script: Zeile 12: printf: 13.234324245: Ungültige Zahl. 

Так просто говорит о том, что число я дал Printf недействителен ...

мне нужно запустить Printf ли по-другому?

редактировать: Проблема, как представляется, на вычислении числа:

rt=$(printf "%.3f" $(echo "$res2 - $res1"|bc)) 

, как я могу сказать бв использовать , вместо .?

ответ

4

Ваша проблема связана для установки LC_NUMERIC, который Баш следует при разборе argumen ts до printf.

Я нахожу это поведение сомнительным. Ksh93 также анализирует числа в соответствии с LC_NUMERIC, в то время как pdksh и тире хотят, чтобы точка разделилась в аргументе, а zsh принимает либо точку, либо локальный формат. POSIX не говорит, поскольку указанный формат с плавающей запятой является необязательным в printf (LC_NUMERIC должен соблюдаться при печати номеров).

В качестве пользователя я рекомендую никогда не устанавливать LC_NUMERIC и LC_COLLATE, за исключением особых условий, когда вы уверены, что хотите их поведения. Это означает, что вы не используете LANG и вместо этого устанавливаете определенные категории; большинству людей требуется только LC_CTYPE (кодировка символов), LC_MESSAGES (язык сообщений) и LC_TIME (формат даты и времени). В сценарии вы можете переопределить все категории, установив LC_ALL или определенную категорию, установив его (настройка LANG только переопределяет $LANG, а не пользовательский набор $LC_NUMERIC).

#!/bin/sh 
LC_NUMERIC=C LC_COLLATE=C 
printf "%.3f" 13.234324245 
2

Это, вероятно, проблема языка - я думаю, что на немецком десятичном разделителе есть запятая ,, а не период .. Попробуйте использовать 13,234324245 в качестве значения.

+0

Что интересно –

+0

, но тогда, как я могу это сделать, когда поплавок пришедшего из нашей эры? это так? D: – reox

+0

Вероятно, самая простая вещь в этом случае - использовать решение @ J-16 и заставить LANG = C. –

2

Просто сделать $(LANG=C printf "%.3f" 13.234324245), просто установите LANG по этой команде

+2

Я рекомендую установить «LC_NUMERIC», а не «LANG», чтобы также переопределить пользовательский набор «LC_NUMERIC». Или даже 'LC_ALL', который превосходит их всех. – Gilles

1

Вы можете использовать другие printf реализации: с не встроенная_команда_оболочки/USR/бен/Printf:

% # LANG is ru_RU.UTF8, decimal separator is comma 
% /usr/bin/printf %.3f 3.14 
3,140 
% /usr/bin/printf %.3f 3,14 
/usr/bin/printf: 3,14: значение преобразовано не полностью 
3,000 
% LANG=C /usr/bin/printf %.3f 3,14 
printf: 3,14: value not completely converted 
3.00 

С zsh встроено Printf реализация:

% printf %.3f 3.14 
3,140 
% printf %.3f 3,14 
3,140 

 Смежные вопросы

  • Нет связанных вопросов^_^