Базовый анализ текстового чата WhatsApp :количество символов участников

Решение XSLT 2.0:

<xsl:template match="tag2">
  <tag2>
    <xsl:value-of select="distinct-values(tokenize(., '&#xa;'))"/>
  </tag2>
</xsl:template>
0
22.10.2020, 02:52
2 ответа

Тот же подход, что и у @dani -garcia. Сначала разделите файл на tabотдельный:

cat file | 
  tr "\n" "\000" | 
  sed "s/\x0\[/\n/g" | 
  sed "1 s/\[//; s/\]/\t/1; s/:/\t/2; s/\x0/ /g" |
  sed -E "s/(^[^,]+), ([0-9]{1,2}).([0-9]{2}).([0-9]{4})/\4-\3-\2 \1/" 

2020-09-25 3:14 pm      James Smith     Hello!
2020-09-25 6:42 pm      John Doe        hi
2020-09-25 6:43 pm      James Smith     I was wondering.. if blah blah and also blah
2020-09-25 6:45 pm      James Smith     blah blah blah blah...

путем trпреобразования всех \newlines вnull

cat file | tr "\n" "\000" | 

затем с помощьюsedgлокально повторно вставьте \newlines везде, где у вас есть шаблонnull[

sed "s/\x0\[/\n/g" | 

окончательно привести в порядок отдельные строки, потеряв ведущую [в строке1

sed "1 s/\[//; 

замена первого ]на \tab

    s/\]/\t/1;

замена второго :на \tab

    s/:/\t/2;

и, наконец, замените все оставшиеся nullна , чтобы избежать объединения слов вместе, где они были первоначально разделены линией \newline

    s/\x0/ /g"

и рассортируйте свои даты, чтобы они хорошо рассортировались

    sed -E "s/(^[^,]+), ([0-9]{1,2}).([0-9]{2}).([0-9]{4})/\4-\3-\2 \1/" 

Теперь ваши поля разделены, вы можете сортировать, группировать, считать или делать что угодно по желанию..

| awk -F'\t' '{chats[$2]++; words[$2]+=split($3,tmp," "); chars[$2]+=length($3)}
   END{for (who in chats){
     S=(chats[who]==1)?"":"s";
     s=(words[who]==1)?"":"s";
     print who" sent "chats[who]" message"S" with "words[who]" word"s" and "chars[who]" characters"}}'

James Smith sent 3 messages with 14 words and 73 characters
John Doe sent 1 message with 1 word and 2 characters
2
18.03.2021, 23:01

Вы можете разделить каждое сообщение на три части (дата, человек, сообщение ), а затем использовать массивы awk, проиндексированные по условию, которое должно быть выполнено, и, наконец, распечатать все значения в массиве, например:

awk '{printf "%s%s", (NR>1&&/^\[.*\]/?"\n":""),$0}END{print " "}' test.txt | sed 's/\(^\[.*\]\) \(.*\): \(.*\)/\1\t\2\t\3/g' | awk 'BEGIN{FS="\t"} {arr[$2] =arr[$2]$3} END{for (i in arr) print length(arr[i]),i}'

является test.txtвашим входным файлом.

Пояснение:

Первая команда(awk '{printf "%s%s", (NR>1&&/^\[.*\]/?"\n":""),$0}END{print " "}' test.txt )удаляет символы новой строки, если строка не начинается с [blahblahblah], т.е. это не новое сообщение, поэтому все сообщение будет в одной строке.

Вторая команда(sed 's/\(^\[.*\]\) \(.*\): \(.*\)/\1\t\2\t\3/g')разделяет каждую строку на три части :дату (с шаблоном [.*]), человека (между датой и двоеточием )и сообщение. Затем он выводит каждую строку, каждая часть которой разделена табуляцией.

Наконец, третья команда(awk 'BEGIN{FS="\t"} {arr[$2] =arr[$2]$3} END{for (i in arr) print length(arr[i]),i}')использует массивы awk, проиндексированные человеком, и выводит длину конкатенации сообщений для каждого человека.

Предположения

  • дата ограничена [и ]и не содержит этих символов между ними.
  • Имя человека не содержит двоеточия
  • Сообщения могут содержать такие строки, как [6:45 pm, 25/09/2020], если они не находятся в начале новой строки.

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

Вероятно, это не самый эффективный способ, но он работает.

0
18.03.2021, 23:01

Теги

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