Извлечение части строк с определенным рисунком и суммирование цифр с помощью bash - PullRequest
0 голосов
/ 20 сентября 2018

Я только изучаю скрипты bash и команды, и мне нужна помощь с этим заданием.

У меня есть текстовый файл, который содержит следующий текст, и мне нужно:

  1. Извлечьguest name (1.1.1 ..)
  2. Суммируйте гостевой результат и выводите гостевое имя с результатом.

Я использовал sed с простым регулярным выражением, чтобы извлечь имя и цифры, ноя понятия не имею, как суммировать числа, потому что у гостя есть несколько строк записи, как вы можете видеть в текстовом файле. Примечание: я не могу использовать awk для обработки

Вот мой код:

cat file.txt | sed -E 's/.*([0-9]{1}.[0-9]{1}.[0-9]{1}).*([0-9]{1})/\1 \2/'

И результат:

1.1.1 4
2.2.2 2
1.1.1 1
3.3.3 1
2.2.2 1

Здесьэто TXT-файл:

Guest 1.1.1 have "4
Guest 2.2.2 have "2
Guest 1.1.1 have "1
Guest 3.3.3 have "1
Guest 2.2.2 have "1

и вывод должен быть:

1.1.1 = 5
2.2.2 = 3
3.3.3 = 1

Заранее спасибо

Ответы [ 3 ]

0 голосов
/ 20 сентября 2018

ОК - так как это классное задание, я расскажу вам, как я это сделал, и позволю вам написать код.

Сначала я отсортировал файл.Затем я читаю файл по одной строке за раз.Если имя изменилось, я распечатал предыдущее имя и счетчик и установил значение счетчика в этой строке.Если имя не изменилось, я добавил значение в счетчик.

0 голосов
/ 20 сентября 2018

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

В конце выполните цикл по массиву, распечатайте индексы и значения.

Этонамного короче.

0 голосов
/ 20 сентября 2018

Я знаю, что ваш учитель не позволит вам использовать awk, но, помимо этого одного упражнения, вы пытаетесь научиться писать сценарии оболочки, к вашему сведению, вот как вы действительно выполняете эту работу в сценарии оболочки:

$ awk -F'[ "]' -v OFS=' = ' '{sum[$2]+=$NF} END{for (id in sum) print id, sum[id]}' file
3.3.3 = 1
2.2.2 = 3
1.1.1 = 5

и вот эквивалент встроенных команд bash, который может или не может быть тем, что вы изучали в классе, а может или не может быть тем, чего ожидает ваш учитель:

$ cat tst.sh
#!/bin/env bash
declare -A sum

while read -r _ id _ cnt; do
    (( sum[$id] += "${cnt#\"}" ))
done < "$1"

for id in "${!sum[@]}"; do
    printf '%s = %d\n' "$id" "${sum[$id]}"
done

$ ./tst.sh file
1.1.1 = 5
2.2.2 = 3
3.3.3 = 1

См. https://www.artificialworlds.net/blog/2012/10/17/bash-associative-array-examples/ о том, как я использую ассоциативный массив.Это будет на несколько порядков медленнее, чем сценарий awk, и я не уверен на 100%, что он пуленепробиваемый (поскольку оболочка не предназначена для обработки текста, есть много предостережений и ловушек), но он будет работать длявведенные вами данные.

...