更新

更新

我有对话转录的文本文件,例如:

Speaker1: Hello. 
Speaker2: Hi. 
Speaker2: How are you? 
Speaker1: Well thanks.

我想数一下说话者有多少次变化从一行到另一行。因此,对于本示例,它将是 2(第 1 行到第 2 行,第 3 行到第 4 行,但不是第 2 行到第 3 行)。

答案1

$ awk -F':' '(NR>1) && ($1!=prev){c++} {prev=$1} END{print c+0}' file
2

答案2

Python 模块itertools有一个方法groupby,只要键值发生变化,就会对键上的数据进行分组。我们将冒号分隔的第一个字段作为我们的键并围绕它进行分组。

python3 -c 'import sys, itertools as it
k,g = -1,lambda x: x.split(":")[0]
with open(sys.argv[1]) as f:
  for t in it.groupby(f,g): k += 1
print(k)
' file
2

GNU sed可以通过一次查看两行来完成。当冒号分隔的第一个字段不同时,我们会在保留处附加换行符。在 eof 处,在删除一个换行符后打印保留,以说明打印时 sed 隐式添加的换行符。

sed -En '
  $!N
  /^([^:]+:).*\n\1/!{x;s/$/\n/;x;}
  $!D
  g;s/.//p
' file|wc -l

Perl 在 slurp 模式 (0777) 下,使用正则表达式的功能,删除在冒号上分隔的相同第一个字段的连续重复行。然后计算换行符的数量。

perl -pl -0777 -e '
  s/^(([^:]+:).*\n)(?:\2.*\n)+/$1/mg;
  $_ = tr/\n// -1;
' file

答案3

累积的“管道”方法如下所示:

  • 剪切说话者后面的所有内容(第一个冒号):cut -f1 -d:
  • 消除重复:uniq
  • 计数行:wc -l

因此,cut -f1 -d: < yourfile | uniq | wc -l应该会产生期望的结果。

更新

正如 @EdMorton 观察到的,结果相差一(变化行数减一,上面算的是行数)。如果您可以管理它,请考虑到这一点。否则,您可以添加一个阶段来跳过uniq:之后的第一行uniq | tail -n +2

答案4

使用 Raku(以前称为 Perl_6)

raku -e '(-1 + slurp.split(/<[:\v]>/)[0,2,4...*]>>.match(/\d+$/).[0..(*-2)]>>.Int.squish.elems).say;'

或者

raku -e '(-1 + slurp.comb(/ ^^ \w+ <(\d+)> \: \s /).squish.elems).say;'

简而言之(上面的第二个解决方案),slurp文件comb选择(按顺序)匹配^^行首、\w+alnum(s)、\:冒号和\s空格的元素,使用<(…)>运算符删除除数字之外的所有内容,squish相邻的相同数字只留下一个,获取元素数量elems,然后-1(减一)得出say答案。

示例输入(OP,重复 2X):

Speaker1: Hello. 
Speaker2: Hi. 
Speaker2: How are you? 
Speaker1: Well thanks..
Speaker1: Hello. 
Speaker2: Hi. 
Speaker2: How are you? 
Speaker1: Well thanks..
Speaker1: Hello. 
Speaker2: Hi. 
Speaker2: How are you? 
Speaker1: Well thanks..

示例输出 ( perl6 -e 'slurp.comb(/ ^^ \w+ <(\d+)> \: \s /).say;')

(1 2 2 1 1 2 2 1 1 2 2 1)

示例输出 ( perl6 -e 'slurp.comb(/ ^^ \w+ <(\d+)> \: \s /).squish.say;')

(1 2 1 2 1 2 1)

示例输出(最后,从顶部开始的第二行代码):

6

https://raku.org

相关内容