Команда оболочки для суммирования целых чисел по одной строке
Узнайте самые эффективные команды оболочки для суммирования целых чисел из ввода по строкам. Изучите методы AWK, paste+BC и циклов оболочки с сравнением производительности и лучшими практиками обработки файлов журнала.
Какая команда оболочки может суммировать целые числа, по одному на строку, из входных данных?
Я работаю с файлом журнала, содержащим измерения времени. После использования grep и sed для извлечения соответствующих значений времени (по одному на строку), мне нужно вычислить их общую сумму. Я пробовал использовать expr в прошлом, но я не уверен, что это лучший подход для этой задачи, поскольку он, кажется, плохо обрабатывает последовательный ввод.
Какой самый эффективный способ суммировать несколько целых чисел из ввода построчно в среде оболочки?
Наиболее эффективные способы суммирования целых чисел из построчного ввода в оболочках включают команду awk за её простоту и производительность, комбинацию paste и bc для больших наборов данных, и циклы оболочки для простых случаев использования. Подход awk '{sum+=$1} END{print sum}' обычно предпочтителен, так как он эффективно обрабатывает большие файлы и автоматически пропускает нечисловые строки.
Содержание
- Общие методы суммирования целых чисел
- Подход AWK: Наиболее рекомендуемое решение
- Комбинация Paste и BC
- Методы циклов оболочки
- Сравнение производительности
- Обработка крайних случаев
- Лучшие практики для скриптинга оболочки
Общие методы суммирования целых чисел
При работе с извлеченными измерениями времени из файлов журнала у вас есть несколько подходов в оболочке. Каждый метод имеет разные преимущества в terms of скорости, простоты и надежности.
Наиболее часто рекомендуемые подходы включают:
- AWK - Лучший баланс между производительностью и простотой
- Paste + BC - Отлично подходит для очень больших наборов данных
- Циклы оболочки - Простые, но менее эффективные для больших файлов
Согласно Unix & Linux Stack Exchange, разные методы могут значительно различаться по производительности, особенно с большими наборами данных.
Подход AWK: Наиболее рекомендуемое решение
Команда awk обычно считается лучшим подходом для суммирования целых чисел из построчного ввода благодаря своей эффективности и простоте.
Базовая команда AWK:
awk '{sum+=$1} END{print sum}' inputfile
Использование с pipe:
grep "timing" logfile | sed 's/.*time://' | awk '{sum+=$1} END{print sum}'
Ключевые преимущества:
- Высокая производительность - Обрабатывает файлы быстро даже с миллионами строк
- Автоматическая обработка ошибок - Автоматически пропускает нечисловые строки
- Простой синтаксис - Легко запомнить и модифицировать
- Работает как с файлами, так и со стандартным вводом
Как упоминается в руководстве LinuxSimply, awk особенно эффективен для извлечения и суммирования чисел из различных форматов файлов.
Расширенные решения AWK:
# Пропускать пустые строки и нечисловые значения
awk 'NF && $1 ~ /^[0-9]+$/ {sum+=$1} END{print sum}'
# Обработка чисел с плавающей точкой
awk '{sum+=$1} END{printf "%.2f\n", sum}'
# Показать количество и среднее значение
awk '{sum+=$1; count++} END{print "Total:", sum, "Count:", count, "Average:", sum/count}'
Комбинация Paste и BC
Для чрезвычайно больших наборов данных или когда требуется максимальная производительность, комбинация paste и bc может быть очень эффективной.
Базовая команда:
paste -sd+ inputfile | bc
Использование с pipe:
grep "timing" logfile | sed 's/.*time://' | paste -sd+ | bc
Как это работает:
paste -sd+объединяет все строки с операторами+bcвыполняет математический расчет
Согласно обсуждению на Unix Stack Exchange, этот метод может быть значительно быстрее, чем awk для очень больших файлов, как отмечено в сравнениях производительности, где решения на основе dc рекомендовались для скорости.
Вариации:
# Использование dc для потенциально лучшей производительности
paste -sd= inputfile | dc
# С bc для поддержки чисел с плавающей точкой
paste -sd+ inputfile | bc -l
Методы циклов оболочки
Для простых случаев или когда требуется больше контроля над процессом, традиционные циклы оболочки могут быть эффективны.
Цикл While с Read:
sum=0
while read -r num; do
((sum += num))
done < inputfile
echo $sum
Цикл For с подстановкой команды:
sum=0
for num in $(cat inputfile); do
((sum += num))
done
echo $sum
Pipe с циклом While:
sum=0
grep "timing" logfile | sed 's/.*time://' | while read -r num; do
((sum += num))
done
echo $sum
Как показано в решении Ask Ubuntu, циклы оболочки обеспечивают простые арифметические операции, но могут быть менее эффективными для больших файлов.
Сравнение производительности
Разные методы показывают значительные различия в производительности, особенно с большими наборами данных:
| Метод | Малые файлы | Большие файлы | Использование памяти | Простота использования |
|---|---|---|---|---|
| AWK | Хорошо | Отлично | Низкое | Легко |
| Paste + BC | Хорошо | Отлично | Низкое | Умеренно |
| Циклы оболочки | Хорошо | Плохо | Низкое | Легко |
На основе тестов производительности, упомянутых в обсуждениях Stack Overflow, paste + bc может быть самым быстрым для очень больших файлов, в то время как awk обеспечивает лучший баланс скорости и удобства использования для большинства случаев.
Сравнение производительности на Stack Overflow показало, что для файлов с десятками миллионов строк paste + bc завершался за доли секунды, в то время как другие методы занимали минуты.
Обработка крайних случаев
Реальные данные часто содержат проблемы, требующие специальной обработки:
Пустые строки:
# Версия AWK, пропускающая пустые строки
awk 'NF && $1 ~ /^[0-9]+$/ {sum+=$1} END{print sum}'
# Версия с циклом оболочки
sum=0
while read -r num || [ -n "$num" ]; do
if [[ "$num" =~ ^[0-9]+$ ]]; then
((sum += num))
fi
done
Нечисловые строки:
# Сначала отфильтровать нечисловые строки
grep -E '^[0-9]+$' inputfile | awk '{sum+=$1} END{print sum}'
# Или использовать сопоставление шаблонов AWK
awk '$1 ~ /^[0-9]+$/ {sum+=$1} END{print sum}'
Числа с плавающей точкой:
# Использовать AWK с printf для форматирования
awk '{sum+=$1} END{printf "%.2f\n", sum}'
# Или использовать bc для точности
paste -sd+ inputfile | bc -l
Алгоритм суммирования Кахана может быть полезен для поддержания точности при суммировании многих чисел с плавающей точкой, хотя это обычно обрабатывается автоматически awk и bc.
Лучшие практики для скриптинга оболочки
При создании надежных скриптов оболочки для суммирования целых чисел, рассмотрите эти лучшие практики:
Обработка ошибок:
#!/bin/bash
input_file="${1:-/dev/stdin}"
if [ ! -r "$input_file" ]; then
echo "Ошибка: Невозможно прочитать входной файл" >&2
exit 1
fi
sum=$(awk '{sum+=$1} END{print sum}' "$input_file")
echo "Итого: $sum"
Функция для повторного использования:
sum_integers() {
local input="${1:-/dev/stdin}"
awk '{sum+=$1} END{print sum}' "$input"
}
# Использование:
sum_integers "numbers.txt"
grep "time" logfile | sed 's/.*time://' | sum_integers
Валидация:
# Убедиться, что ввод содержит только допустимые числа
validate_numbers() {
local input="$1"
if ! awk 'BEGIN{exit} !/^[0-9]+(\.[0-9]+)?$/ {exit 1}' "$input"; then
echo "Предупреждение: Ввод содержит нечисловые значения" >&2
fi
}
Как отмечено в лучших практиках для продвинутого скриптинга Bash, корпоративные скрипты должны включать правильную обработку ошибок, валидацию и модульный дизайн.
Заключение
Ключевые выводы:
- AWK - рекомендуемый выбор для большинства случаев использования - он быстрый, надежный и хорошо обрабатывает крайние случаи
- Paste + BC превосходит с очень большими наборами данных или когда максимальная производительность критична
- Циклы оболочки работают для простых случаев, но неэффективны с большими файлами
- Всегда валидируйте ввод для правильной обработки пустых строк и нечисловых значений
- Учитывайте требования к точности при выборе между целыми и числами с плавающей точкой
Рекомендации по действиям:
- Начните с
awk '{sum+=$1} END{print sum}'для ваших измерений времени - Если обрабатываете файлы с миллионами строк, протестируйте оба подхода: AWK и paste+BC
- Создайте повторно используемую функцию в вашем профиле оболочки для общих задач суммирования
- Всегда включайте обработку ошибок в производственных скриптах
Для большинства обработки файлов журнала и анализа времени подход AWK обеспечивает лучший баланс производительности, простоты и надежности. Если вы столкнетесь с проблемами производительности с чрезвычайно большими наборами данных, поэкспериментируйте с методом paste+BC, так как он может обеспечить лучшую пропускную способность.
Источники
- Shell command to sum integers, one per line? - Stack Overflow
- How can I sum numbers on lines in a file - Ask Ubuntu
- How can I quickly sum all numbers in a file? - Unix & Linux Stack Exchange
- Bash command to sum a column of numbers - Stack Overflow
- How to Sum Up Numbers in Bash [Explained With Examples] - LinuxSimply
- 7.13. Summing a List of Numbers - bash Cookbook [Book]
- How to quickly sum all the numbers in a file on Linux? - Tutorialspoint
- Advanced Bash Scripting Best Practices for Enterprise Linux - Medium