Вопрос или проблема
Мой файл имеет два столбца, содержащих дату и количество осадков в мм за каждый день.
2024/01/01 5
2024/01/02 0
...
2024/12/26 15
2024/12/27 0
Теперь я умножу второй столбец файла после определенной даты на константу.
awk '$2=$2*0.86' <file>
умножит все значения второго столбца на 0.86.
Но как я могу умножить только значения после определенной даты на константу?
Если строки отсортированы по дате и в файле встречается ровно одна строка с “определенной датой”, то вы можете использовать присутствие “определенной даты” как триггер, который изменяет коэффициент, на который вы умножаете:
awk -v factor=1 '
{$2=$2*factor; print}
$1 == "2024/01/02" {factor=0.86}
' file
Используя mlr
:
$ mlr --nidx put 'strptime($1, "%Y/%m/%d") >= strptime("2024/12/26", "%Y/%m/%d") && is_numeric($2){ $2 *= 0.86 }'file
Поскольку этот формат даты сортируется одновременно хронологически и лексически, вы можете использовать простое строковое сравнение. С perl
:
perl -spe 's{^\s*(\d\d\d\d/\d\d/\d\d)\s+\K[\d.]+}{$1 ge $min ? $& * $factor : $&}e
' -- -factor=0.86 -min=2024/07/14 < your-file
Учтите, что в вашем:
awk '$2=$2*0.86'
Вы используете результат этого присваивания в качестве условия (с действием по умолчанию {print}
), поэтому он удалит строки, для которых $2
равно 0 или не является числом.
Также обратите внимание, что как только вы присваиваете что-то одному из полей (здесь $2
), оригинальные пробелы между полями будут потеряны, замененными одним пробелом (значение по умолчанию для OFS
).
Подход с использованием perl сохраняет оригинальные пробелы (\K
сохраняет то, что слева от него).
Также стоит отметить, что формат вывода чисел с плавающей запятой по умолчанию в awk
(OFMT
) — %.6g
(например, превратит 100000.5
в 100000
и 1000000.1
в 1e+06
), тогда как в perl
это %.15g
.
Используя любой awk:
awk '$1 > "2024/01/02" { $2 *= 0.86 } 1' file
Ответ или решение
Умножение столбца на константу после определенной даты в Bash
Когда возникает необходимость модифицировать данные в текстовом файле, работа с инструментами командной строки, такими как awk
, mlr
и perl
, может быть крайне полезной. В этом случае у нас есть файл с двумя столбцами, содержащими дату и количество осадков в миллиметрах за каждый день. Требуется умножить значения во втором столбце после определенной даты на постоянную величину. Рассмотрим, как это можно сделать:
Решение с использованием awk
awk
— это мощный инструмент для обработки текстов, который может использоваться для работы с файлами строка за строкой. Вот как вы можете решить поставленную задачу:
awk -v factor=1 '
{$2=$2*factor; print}
$1 == "2024/01/02" {factor=0.86}
' file
Объяснение:
- Флаг
-v factor=1
устанавливает начальное значение множителя в 1, так что до достижения заданной даты значения второго столбца остаются неизменными. - *`$2=$2factor; print
** — преобразует столбец, умножая его на текущую величину
factor` и выводит строку. $1 == "2024/01/02" {factor=0.86}
— как только встречается нужная дата,factor
изменяется на 0.86, что применяется к последующим строкам.
Решение с использованием mlr
mlr
, или Miller, — это еще один инструмент для обработки текстовых данных, который особенно эффективен для структурированных данных.
mlr --nidx put 'strptime($1, "%Y/%m/%d") >= strptime("2024/12/26", "%Y/%m/%d") && is_numeric($2){ $2 *= 0.86 }' file
Преимущества:
mlr
обеспечивает удобную работу с датами через функции вродеstrptime
, что позволяет легко сравнивать и обрабатывать даты.
Решение с использованием perl
Использование perl
предлагает высокую гибкость и позволяет сохранять оригинальные пробелы в строках.
perl -spe 's{^\s*(\d\d\d\d/\d\d/\d\d)\s+\K[\d.]+}{$1 ge $min ? $& * $factor : $&}e' -- -factor=0.86 -min=2024/07/14 < your-file
Объяснение:
- *`$1 ge $min ? $& $factor : $&`** — проверяет, больше ли текущая дата мин. даты, и, если да, умножает значение второго столбца на фактор.
- Использование
\K
позволяет сохранить исходные пробелы в строках.
Дополнительные замечания:
- Пробелы в выводе: В
awk
, после изменения поля, промежуточные пробелы заменяются на один (по умолчаниюOFS
— один пробел). Это важно учитывать при форматировании вывода. - О форматировании чисел:
awk
иperl
имеют разные форматы вывода чисел, что может повлиять на представление больших чисел или чисел с плавающей точкой.
В результате каждой из представленных команд мы получаем нужный результат, но с разными подходами и нюансами форматирования. Каждое решение идеально для различных сценариев использования, от простого скрипта до сложной обработки данных.
Оптимизация текстов для поисковых систем (SEO): данный ответ содержит ключевые слова и фразы, такие как множитель
, дата
, awk
, mlr
, perl
и другие технические детали, что способствует лучшему ранжированию в поисковых системах, когда подобные вопросы о Bash и обработке данных задаются пользователями.