Как найти, какое поле в моем CSV-файле появляется чаще всего с помощью сценария оболочки? - PullRequest
0 голосов
/ 21 октября 2019

Я изучаю, как использовать сценарий оболочки, и у меня есть CSV-файл, содержащий 5 столбцов name forname telephone room email, и я хочу найти, какой room содержит наибольшее количество людей.

На данный момент я выполнил следующий код и застрял в той части, где мне нужно подсчитать, в какой комнате больше сотрудников или какая комната больше всего отображается в файле

input="x.csv"
while read line; do
    room=$(echo $line | cut -d \; -f 4)
    if [ -n "$room" ]; then

    fi
done < ${input}

Ответы [ 3 ]

2 голосов
/ 21 октября 2019

Парсинг CSV-файлов, как это больно.

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

awk -F';' '# CSV delimiter set to ;
    $4{ # This block will be executed if room value is not null
        n_persons[$4] += 1
        if (n_persons[$4] > max){
            max = n_persons[$4] #current max of employees per room
            room_max = $4 #current room that has most employees
        }
    }
    END{#this block is executed after reading the file
        print room_max
    }
' <file>
2 голосов
/ 21 октября 2019

Подсчет вхождений уникальных значений, вероятно, лучше всего сделать с помощью uniq -c. Таким образом, чтобы подсчитать записи для каждой комнаты в отдельности, вам нужно извлечь список, содержащий столбец room. awk, вероятно, лучший инструмент в среде bash для этого. Например:

#!/bin/bash
input="x.csv"

awk '{print $4}' $input | sort | uniq -c

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

      4 room1b
      2 room1
      1 room2
      1 room3

Для более сложного анализа выполните Указание Корентина для расширения ввода awk.

1 голос
/ 21 октября 2019

Если вы настаиваете на использовании Bash, у него есть ассоциативные массивы . Я не совсем уверен, как бы вы отсортировали их в обычном bash, и использование только звуков bash немного сложнее для этого. Возможно, awk будет работать лучше?

В Bash вместо оригинального подхода я бы сделал это с помощью трубопровода:

  1. cut (чтобы выбрать столбец, как выуже сделано)
  2. sort (для сортировки значений, чтобы их можно было обработать с помощью uniq)
  3. uniq -c (для подсчета количества вхождений в значении одного столбца)
  4. sort -nr (для сортировки по количеству вхождений, по убыванию - по возрастанию)
  5. head (для получения только наиболее частых)

Что-то вроде (не проверено):

cut -d \; -f 4 input.csv \
  | sort \
  | uniq -c \
  | sort -nr \
  | head -1

Если вам нужно отфильтровать некоторые строки, я бы добавил grep -v после cut. Не нужно использовать условные операторы, пока циклы, read встроены. \ в конце строки говорит bash, что эта «строка» продолжается на следующей строке.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...