Другое

Команда оболочки для суммирования целых чисел по одной строке

Узнайте самые эффективные команды оболочки для суммирования целых чисел из ввода по строкам. Изучите методы AWK, paste+BC и циклов оболочки с сравнением производительности и лучшими практиками обработки файлов журнала.

Какая команда оболочки может суммировать целые числа, по одному на строку, из входных данных?

Я работаю с файлом журнала, содержащим измерения времени. После использования grep и sed для извлечения соответствующих значений времени (по одному на строку), мне нужно вычислить их общую сумму. Я пробовал использовать expr в прошлом, но я не уверен, что это лучший подход для этой задачи, поскольку он, кажется, плохо обрабатывает последовательный ввод.

Какой самый эффективный способ суммировать несколько целых чисел из ввода построчно в среде оболочки?

Наиболее эффективные способы суммирования целых чисел из построчного ввода в оболочках включают команду awk за её простоту и производительность, комбинацию paste и bc для больших наборов данных, и циклы оболочки для простых случаев использования. Подход awk '{sum+=$1} END{print sum}' обычно предпочтителен, так как он эффективно обрабатывает большие файлы и автоматически пропускает нечисловые строки.


Содержание


Общие методы суммирования целых чисел

При работе с извлеченными измерениями времени из файлов журнала у вас есть несколько подходов в оболочке. Каждый метод имеет разные преимущества в terms of скорости, простоты и надежности.

Наиболее часто рекомендуемые подходы включают:

  1. AWK - Лучший баланс между производительностью и простотой
  2. Paste + BC - Отлично подходит для очень больших наборов данных
  3. Циклы оболочки - Простые, но менее эффективные для больших файлов

Согласно Unix & Linux Stack Exchange, разные методы могут значительно различаться по производительности, особенно с большими наборами данных.


Подход AWK: Наиболее рекомендуемое решение

Команда awk обычно считается лучшим подходом для суммирования целых чисел из построчного ввода благодаря своей эффективности и простоте.

Базовая команда AWK:

bash
awk '{sum+=$1} END{print sum}' inputfile

Использование с pipe:

bash
grep "timing" logfile | sed 's/.*time://' | awk '{sum+=$1} END{print sum}'

Ключевые преимущества:

  • Высокая производительность - Обрабатывает файлы быстро даже с миллионами строк
  • Автоматическая обработка ошибок - Автоматически пропускает нечисловые строки
  • Простой синтаксис - Легко запомнить и модифицировать
  • Работает как с файлами, так и со стандартным вводом

Как упоминается в руководстве LinuxSimply, awk особенно эффективен для извлечения и суммирования чисел из различных форматов файлов.

Расширенные решения AWK:

bash
# Пропускать пустые строки и нечисловые значения
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 может быть очень эффективной.

Базовая команда:

bash
paste -sd+ inputfile | bc

Использование с pipe:

bash
grep "timing" logfile | sed 's/.*time://' | paste -sd+ | bc

Как это работает:

  • paste -sd+ объединяет все строки с операторами +
  • bc выполняет математический расчет

Согласно обсуждению на Unix Stack Exchange, этот метод может быть значительно быстрее, чем awk для очень больших файлов, как отмечено в сравнениях производительности, где решения на основе dc рекомендовались для скорости.

Вариации:

bash
# Использование dc для потенциально лучшей производительности
paste -sd= inputfile | dc

# С bc для поддержки чисел с плавающей точкой
paste -sd+ inputfile | bc -l

Методы циклов оболочки

Для простых случаев или когда требуется больше контроля над процессом, традиционные циклы оболочки могут быть эффективны.

Цикл While с Read:

bash
sum=0
while read -r num; do
    ((sum += num))
done < inputfile
echo $sum

Цикл For с подстановкой команды:

bash
sum=0
for num in $(cat inputfile); do
    ((sum += num))
done
echo $sum

Pipe с циклом While:

bash
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 завершался за доли секунды, в то время как другие методы занимали минуты.


Обработка крайних случаев

Реальные данные часто содержат проблемы, требующие специальной обработки:

Пустые строки:

bash
# Версия 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

Нечисловые строки:

bash
# Сначала отфильтровать нечисловые строки
grep -E '^[0-9]+$' inputfile | awk '{sum+=$1} END{print sum}'

# Или использовать сопоставление шаблонов AWK
awk '$1 ~ /^[0-9]+$/ {sum+=$1} END{print sum}'

Числа с плавающей точкой:

bash
# Использовать AWK с printf для форматирования
awk '{sum+=$1} END{printf "%.2f\n", sum}'

# Или использовать bc для точности
paste -sd+ inputfile | bc -l

Алгоритм суммирования Кахана может быть полезен для поддержания точности при суммировании многих чисел с плавающей точкой, хотя это обычно обрабатывается автоматически awk и bc.


Лучшие практики для скриптинга оболочки

При создании надежных скриптов оболочки для суммирования целых чисел, рассмотрите эти лучшие практики:

Обработка ошибок:

bash
#!/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"

Функция для повторного использования:

bash
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

Валидация:

bash
# Убедиться, что ввод содержит только допустимые числа
validate_numbers() {
    local input="$1"
    if ! awk 'BEGIN{exit} !/^[0-9]+(\.[0-9]+)?$/ {exit 1}' "$input"; then
        echo "Предупреждение: Ввод содержит нечисловые значения" >&2
    fi
}

Как отмечено в лучших практиках для продвинутого скриптинга Bash, корпоративные скрипты должны включать правильную обработку ошибок, валидацию и модульный дизайн.


Заключение

Ключевые выводы:

  1. AWK - рекомендуемый выбор для большинства случаев использования - он быстрый, надежный и хорошо обрабатывает крайние случаи
  2. Paste + BC превосходит с очень большими наборами данных или когда максимальная производительность критична
  3. Циклы оболочки работают для простых случаев, но неэффективны с большими файлами
  4. Всегда валидируйте ввод для правильной обработки пустых строк и нечисловых значений
  5. Учитывайте требования к точности при выборе между целыми и числами с плавающей точкой

Рекомендации по действиям:

  • Начните с awk '{sum+=$1} END{print sum}' для ваших измерений времени
  • Если обрабатываете файлы с миллионами строк, протестируйте оба подхода: AWK и paste+BC
  • Создайте повторно используемую функцию в вашем профиле оболочки для общих задач суммирования
  • Всегда включайте обработку ошибок в производственных скриптах

Для большинства обработки файлов журнала и анализа времени подход AWK обеспечивает лучший баланс производительности, простоты и надежности. Если вы столкнетесь с проблемами производительности с чрезвычайно большими наборами данных, поэкспериментируйте с методом paste+BC, так как он может обеспечить лучшую пропускную способность.

Источники

  1. Shell command to sum integers, one per line? - Stack Overflow
  2. How can I sum numbers on lines in a file - Ask Ubuntu
  3. How can I quickly sum all numbers in a file? - Unix & Linux Stack Exchange
  4. Bash command to sum a column of numbers - Stack Overflow
  5. How to Sum Up Numbers in Bash [Explained With Examples] - LinuxSimply
  6. 7.13. Summing a List of Numbers - bash Cookbook [Book]
  7. How to quickly sum all the numbers in a file on Linux? - Tutorialspoint
  8. Advanced Bash Scripting Best Practices for Enterprise Linux - Medium
Авторы
Проверено модерацией
Модерация