我有这个文件:
90 1
120 1
Transition
150 1
Transition
165 1
Transition
180 1
225 1
240 1
255 1
270 1
Transition
285 1
Transition
我想要这个输出:
1 2
2 1
3 1
4 5
5 1
这意味着1
第二列在第一次转换之前出现了 2 次。我如何使用 awk/grep 来做到这一点?
答案1
1
如果您想计算每行之前/之间的第二个字段中的次数,Transition
您可以使用awk
类似
awk '$2 == "1" {count++;} /Transition/ {t_count++; print t_count "\t" count; count=0;}' <input file>
每次1
在字段 2 中都会增加一个计数器,并且每次行匹配时Transition
都会打印转换行数的计数,然后打印1
行数。
我的输入文件的输出:
1 2
2 1
3 1
4 5
5 1
答案2
这是一个 Perl 解决方案,使用与埃里克·雷诺夫回答:
$ perl -lane '$F[1]==1 && $c++; if(/Transition/){$k++; print "$k\t$c"; $c=0}' file
1 2
2 1
3 1
4 5
5 1
解释
-l
为每个调用添加换行符print
;-a
启用“awk-mode”,将每个输入行拆分到数组中,@F
以便$F[0]
成为第一个字段和$F[1]
第二个字段。-ne
告诉perl
逐行处理其输入文件并将给定的脚本应用于-e
每一行。$F[1]==1 && $c++;
:$c
如果第二个字段为 则加 11
。if(/Transition/){$k++; print "$k\t$c"; $c=0}'
:如果该行匹配Transition
,则加一,打印和$k
的当前值并设置回 0。$k
$c
$c
答案3
除了“Transition”和“number 其次是 1”之外还有其他行吗?我假设不会。当有两个转换且中间没有任何转换时会发生什么?我假设这不会发生。
你特别要求 awk,所以埃里克的回答是完美的。为了完整起见,我想提交一个没有 awk 的版本:)
| sed 's/.* 1 *$/CountThisLine/' | uniq -c | sed -n 's/CountThisLine//p' | nl -nln
第一个sed
选择要计数的行并使它们相同,同时保持转换,uniq -c
对相同的连续行进行计数,第二个sed
仅保留非转换行并对nl
结果进行编号。
$ cat test.txt \
| sed 's/.* 1 *$/CountThisLine/' \
| uniq -c \
| sed -n 's/CountThisLine//p' \
| nl -nln
1 2
2 1
3 1
4 5
5 1