Как суммировать результаты нескольких команд bash в bash?

Я бы предпочел Python awk во всем, кроме одного -вкладыша. Использование скрипта Python позволит вам легче обрабатывать плохо отформатированные входные данные, а также выполнять регистрацию и обработку ошибок -.

Вот базовый скрипт Python, который выдаст желаемый результат для вашего примера ввода и имеет структуру, наводящую на мысль о том, как вы могли бы построить его дальше, если это необходимо:

#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
"""parse_log.py"""

import sys
from collections import OrderedDict

logfilepath = sys.argv[1]

# Define a function to parse a single block/entry in the log file
def parse_block(block):
    parsed_block = dict()
    lines = block.split("\n")
    for line in lines:
        if line.startswith("Company="):
            parsed_block["Company"] = line[8:]
        elif line.startswith("Req_id="):
            parsed_block["Required_ID"] = line[7:]
        elif line.startswith("Time_taken="):
            parsed_block["Time_Taken"] = line[11:]
        elif line.startswith("Status="):
            parsed_block["Status"] = line[7:]
        else:
            pass
    return parsed_block

# Initialize a list to store the processed entries
parsed_blocks = list()

# Populate the list
with open(logfilepath, "r") as logfile:
    blocks = logfile.read().split("\n\n")
    for block in blocks:
        parsed_block = parse_block(block)
        parsed_blocks.append(parsed_block)

# Print the results
print("Below Request Id took more then expected")
for parsed_block in parsed_blocks:
    print("Request id {}, Time Taken: {}".format(parsed_block["Required_ID"], parsed_block["Time_Taken"]))

Можно запустить так:

python parse_log.py data.log

В вашем примере ввода он производит следующий вывод (в соответствии с запросом):

Below Request Id took more then expected
Request id 1234, Time Taken: 10 sec
Request id 3456, Time Taken: 200 sec
Request id 3001, Time Taken: 15 sec
0
30.09.2020, 22:19
3 ответа

Более простые способы:

awk 'END { print NR }' a1 a2 a3...

или

wc -l a1 a2 a3... | awk 'END { print $1 } '

И, если у вас много файлов, не превышайте лимит длины командной строки:

find. -type f -name 'a[123]' -exec awk 'END { print NR }' {} + |
  {
    while read n; do
      tot=$(( tot + n ))
    done
    echo "$tot"
  }

Если вам нужно придерживаться этого формата (, например. поскольку у вас есть некоторые сложные команды вместо catв ваших примерах ), вы можете использовать арифметическое расширение:

echo $(( $(wc -l <a1) + $(wc -l <a2) + $(wc -l <a3) +... ))

или bc, для более широкого диапазона вариантов расчета:

echo "ibase=10; obase=10; $(wc -l <a1) + $(wc -l <a2) +..." | bc
3
18.03.2021, 23:01

Люди говорят, что

cat a1 | wc -l

— это UUOC(Бесполезное использование кота ), потому что вы могли написать просто

wc -l a1

но на ваш вопрос,вы могли бы найти полезное применение коту:

cat a1 a2 a3... | wc -l

Таким образом, wcвидит один файл (поток )в качестве входных данных и печатает итог.

3
18.03.2021, 23:01

мы суммируем это само по себе. Вы можете передать все файлы одновременно, и мы подсчитаем сумму за вас:

    wc -l a* | tail -n1

Или, если вы хотите пропустить текстовую строку и получить только количество:

    wc -l a* | tail -n1 | cut -d" " -f2

Или используя grep для цифры:

    wc -l a* | tail -n1 | grep -o "[[:digit:]]*"

Или используя другой язык, встроенный в оболочку:

grep -ch '.*' a* | xargs -d \n -I{} python3 -c 'import sys; print(sum(map(int, sys.argv[1].split())))' {}
0
18.03.2021, 23:01

Теги

Похожие вопросы