Печать тысяч разделенных поплавков с помощью GAWK - PullRequest
0 голосов
/ 15 апреля 2009

Я должен обработать какой-то огромный файл с помощью gawk. Моя главная проблема заключается в том, что я должен напечатать несколько поплавков, используя тысячи разделителей. Например: 10000 должно отображаться как 10.000 и 10000,01 как 10.000,01 на выходе.

Я (и Google) придумали эту функцию, но она не работает для чисел с плавающей запятой:

function commas(n) {
  gsub(/,/,"",n)
  point = index(n,".") - 1
  if (point < 0) point = length(n)
    while (point > 3) {
      point -= 3
      n = substr(n,1,point)"."substr(n,point + 1)
    }
  sub(/-\./,"-",n)
  return d n
}

Но с плавающей точкой это не получается.

Теперь я подумываю разделить входные данные на целое число и часть

Отказ от ответственности:

  • Я не программист
  • Я знаю это через какую-то ОБОЛОЧКУ. переменные могут быть установлены тысячи разделителей, но они должны работать в разных средах с разными настройками языка и / или локали.
  • Английский - мой второй язык, извините, если я использую его неправильно

Ответы [ 2 ]

2 голосов
/ 15 апреля 2009

С плавающей точкой это не получается, потому что вы передаете европейские номера (1.000.000,25 на миллион с четвертью). Функция, которую вы дали, должна работать, если вы просто переключаетесь через запятую и точку. Сначала я протестировал бы текущую версию с 1000000.25, чтобы проверить, работает ли она с неевропейскими номерами.

Следующий скрипт awk можно вызвать с помощью "echo 1 | awk -f xx.gawk", и он покажет вам как "нормальную", так и европейскую версию в действии. Выводит:

123,456,789.1234
123.456.789,1234

Очевидно, что вас интересуют только функции, реальный код будет использовать входной поток для передачи значений в функции, а не фиксированную строку.

function commas(n) {
    gsub(/,/,"",n)
    point = index(n,".") - 1
    if (point < 0) point = length(n)
    while (point > 3) {
        point -= 3
        n = substr(n,1,point)","substr(n,point + 1)
    }
    return n
}
function commaseuro(n) {
    gsub(/\./,"",n)
    point = index(n,",") - 1
    if (point < 0) point = length(n)
    while (point > 3) {
        point -= 3
        n = substr(n,1,point)"."substr(n,point + 1)
    }
    return n
}
{ print commas("1234,56789.1234") "\n" commaseuro("12.3456789,1234") }

Функции идентичны, за исключением обработки запятых и точек. Мы назовем их разделителями и десятичными числами в следующем описании:

  • gsub удаляет все существующие разделители, так как мы вернем их обратно.
  • точка находит, где находится десятичная дробь, поскольку это наша отправная точка.
  • если десятичного разделителя нет, оператор if начинается с конца.
  • мы зациклились, когда осталось более трех символов.
  • внутри цикла, мы корректируем положение для вставки разделителя и вставляем его.
  • как только цикл завершится, мы вернем скорректированное значение.
0 голосов
/ 15 апреля 2009

Для ответа на вопрос Пакс :

Прочитайте раздел «Преобразование» руководства по GNU awk , в котором подробно говорится о влиянии вашей переменной среды LOCALE на строковое представление числовых типов.

...