Bash: Как посчитать количество вхождений строки в файле? - PullRequest
0 голосов
/ 16 января 2020

У меня есть файл, который выглядит примерно так:

dog
cat
dog
dog
fish
cat

Я хотел бы написать какой-нибудь код в Bash, чтобы файл был отформатирован как:

dog:1
cat:1
dog:2
dog:3
fish:1
cat:2

Есть идеи, как это сделать? Файл очень большой (> 30 тыс. Строк), поэтому код должен быть несколько быстрым.

Я думаю, что-то вроде l oop ...

Вот так:

while read line; 
     echo "$line" >> temp.txt
     val=$(grep $line temp.txt)
     echo "$val" >> temp2.txt
done < file.txt 

А потом paste -d ':' file1.txt temp2.txt

Однако, Я обеспокоен тем, что это будет очень медленно, так как вы идете построчно. Что думают другие люди?

Ответы [ 3 ]

5 голосов
/ 16 января 2020

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

awk '{print $0 ":" ++freq[$0]}' file

dog:1
cat:1
dog:2
dog:3
fish:1
cat:2
0 голосов
/ 17 января 2020

Awk или sed очень мощные, но это не bash, вот вариант bash

raw=( $(cat file) ) # read file
declare -A index    # init indexed array

for item in ${raw[@]}; { ((index[$item]++)); } # 1st loop through raw data to count items
for item in ${raw[@]}; { echo $item:${index[$item]}; } # 2nd loop change data
0 голосов
/ 16 января 2020

Вот что я придумал:

declare -A arr; while read -r line; do ((arr[$line]++)); echo "$line:${arr[$line]}" >> output_file; done < input_file

Сначала объявите ha sh table arr. Затем прочитайте каждую строку в a для l oop и увеличьте значение в массиве ключом прочитанной строки. Затем выведите строку, а затем значение в хеш-таблице. Наконец добавьте в файл 'out'.

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