Он работает с интернет-кабелем?
Если да, сделайте это:
echo 'deb http://ftp.debian.org/debian/ stretch main contrib non-free' >/etc/apt/sources.list
apt-get update
apt-get install firmware-realtek
Чтобы установить сетевые драйверы...
Перезагрузите компьютер и повторите попытку поиска сетей Wi-Fi.
Если у вас нет возможности подключиться к Интернету по кабелю, загрузите пакет отсюда :http://ftp.us.debian.org/debian/pool/non-free/f/firmware-nonfree/firmware-realtek_20161130-4_all.deb
Сохраните на флешке, откройте флешку на машине с Debian, щелкните правой кнопкой мыши в «папке» флешки, откройте в терминале, установите с помощью:
dpkg -i firmware-realtek_20161130-4_all.deb
Перезагрузите компьютер и повторите попытку поиска сетей Wi-Fi.
Не принимая во внимание вашу проблему с большими числами, я бы написал awk
программу примерно так:
BEGIN {
FS = "\\|~\\^"
OFS= "|~^"
}
$1 == "H" {
header = $0
}
$1 == "R" {
name = $3
sub("T.*", "", name)
sum[name] += $4
cnt[name] += 1
if (cnt[name] == 1)
print header >name ".txt"
print >name ".txt"
}
$1 == "T" {
for (name in sum)
print $1, $2, cnt[name], $4, sum[name] >name ".txt"
}
Для удобства я установил разделитель полей вывода OFS
на |~^
. Это позволяет мне не беспокоиться о вставке его между полями, которые я вывожу. В качестве разделителя полей для ввода FS
используется регулярное выражение, соответствующее этой строке.
Затем у меня есть три основных блока кода:
Один для разбора строки H
. Предполагается, что существует только один из них и что он возникает в начале. Это просто сохраняет строку заголовка в переменной header
.
Один для разбора строк R
. Каждая запись содержит дату, которая должна использоваться в качестве имени выходного файла в 3-м поле. Это анализируется так же, как и вы. Сумма за эту дату накапливается, а также увеличивается счетчик.
Если счетчик равен единице, то есть если мы впервые видим эту конкретную дату, мы записываем заголовок в выходной файл, связанный с этой датой. Затем мы записываем текущую запись в файл.
Последний блок анализирует строку T
. Предполагается, что есть только один из них и что он происходит в конце. Это просто выводит накопленные суммы и подсчеты для каждой отдельной даты в файл, связанный с этой датой, вместе с некоторыми данными из исходной строки T
.
Для поддержки произвольно больших чисел (вы говорите в другом месте , что у вас есть числа, для хранения которых требуется более 100 бит, и поэтому целое число вawk
)будет переполнено, мы используем калькулятор произвольной точности bc
как "сопроцесс" (своего рода вычислительная служба ). Строка с надписью sum[name] += $4
заменена на
if (sum[name] == "") sum[name] = 0
printf "%s + %s\n", sum[name], $4 |& "bc"
"bc" |& getline sum[name]
Для этого требуется GNU awk
(, доступный для большинства систем Unix, так или иначе ).
Это сначала инициализирует сумму для текущей даты нулем, если для этой даты еще нет суммы. Мы делаем это, потому что нам нужно поставить от 0
до bc
для начальной суммы.
Затем мы печатаем выражение, которое bc
должно вычислить, используя специальный |&
конвейер GNUawk
-для записи в сопроцесс. Утилита bc
, которая будет запускаться и работать параллельно с нашим сценарием awk
, выполняет вычисления, а следующая getline
считывает вывод из bc
из другого канала |&
прямо в sum[name]
..
Насколько я понимаю, GNU awk
не будет порождать отдельный bc
процесс для каждого суммирования, а будет поддерживать один bc
процесс, работающий как сопроцесс. Таким образом, это будет медленнее, чем выполнение вычислений внутри awk
изначально, но будет намного быстрее, чем создание отдельного bc
для каждого суммирования.
Для заданных данных будут созданы следующие два файла:
$ cat 2019-03-05.txt
H|~^20200425|~^abcd|~^sum
R|~^abc|~^2019-03-05T12:33:52.27|~^105603.042|~^2018-10-23T12:33:52.27|~^aus
R|~^abc|~^2019-03-05T12:33:52.27|~^2054.026|~^2018-10-24T12:33:52.27|~^usa
R|~^abc|~^2019-03-05T12:33:52.27|~^30.00|~^2018-08-05T12:33:52.27|~^ddd
R|~^abc|~^2019-03-05T12:33:52.27|~^20.00|~^2018-07-23T12:33:52.27|~^audg
T|~^20200425|~^4|~^xxx|~^107707.068
$ cat 2019-03-06.txt
H|~^20200425|~^abcd|~^sum
R|~^abc|~^2019-03-06T12:33:52.27|~^123562388.23456|~^2018-04-12T12:33:52.27|~^hhh
R|~^abc|~^2019-03-06T12:33:52.27|~^10.00|~^2018-09-11T12:33:52.27|~^virginia
R|~^abc|~^2019-03-06T12:33:52.27|~^15.03|~^2018-10-23T12:33:52.27|~^jjj
R|~^abc|~^2019-03-06T12:33:52.27|~^10.04|~^2018-04-08T12:33:52.27|~^jj
T|~^20200425|~^4|~^xxx|~^123562423.30456
Я уже написал код awk для решения этого вопроса , который работает быстрее, чем код, который вы здесь представляете.
Вы уже задавали вопрос о суммировании многих чисел и получении неточного ответа в прошлом. Этот вопрос очень похож на этот другой вопрос Почему существует разница между этими двумя командами суммирования? .
Файл из этого вопроса весил 20 мегабайт и содержал более 700 тысяч строк.
Вы заявили, что ваши файлы находятся в порядке Размер файла составляет от 500 до 600 МБ . Это увеличит количество строк до 10 миллионов строк.
Проблема в том, что цифры для добавления:
может варьироваться в широких пределах :от 3 цифр 12.8
до 28 цифр 1245637.34526234567299999999
.
Сложение 28-значных чисел 10 миллионов раз должно потребовать 28 + 7 = 35 цифр. И это при условии, что цифры не все десятичные или целые числа. Если это возможно, мы говорим о 70 цифрах (35 целых + 35 десятичных дробях ).
Представление в числах с плавающей запятой всегда будет аппроксимацией точного числа, что является фундаментальной проблемой поплавков. Если вам нужна точная сумма, вы должны сложить все их как целые числа.
Решением вашей проблемы может быть использование GNU awk с более длинным числом цифр. По умолчанию в awk числа с плавающей запятой используют 53-битную мантиссу, подходящую только для 15 цифр.
Если вы используете GNU AWK, скомпилированный с помощью MPFR (Multiple Precision Floating -Point Reliably )и GMP (GNU Multiple Precision Arithmetic Library ), результат ее --текст версии должен включать эту информацию (executeawk --version
). В этом случае вы можете использовать больше битов. Чтобы иметь возможность хранить 40-значные числа с плавающей запятой (35 цифр, рассчитанных выше + некоторый запас безопасности ), вам понадобится:
b = ceil(d log2(10)) + 1
b = ceil( 40 * 3.321928 ) + 1 = 133 + 1 = 134 binary digits (bits)
Таким образом, вызов awk должен быть:
awk -M -v PREC=134
Предупреждение :Использование большего количества цифр замедляет работу программы.
И по-прежнему использовать ту же программу awk
awk -M -v PREC=134 '
BEGIN { FS="\\|~\\^"; OFS="|~^" }
$1=="H"{ header=$0; hdr=$2 }
$1=="R"{
t=gensub(/-/, "","g",$3)
file=gensub(/T.*/,"",1,t);
sum[file]+=$4
if(count[file]==0){ print header >file }
count[file]++
print $0 >>file
}
END {
for( i in sum ){
printf "T %s %10d xxx %45.25f",hdr,count[i],"xxx",sum[i] >> i;
close(i)
}
}
' "inputfile"
Для справки :Вы задавали почти один и тот же вопрос снова и снова: