我有一个 bash 命令管道,可以生成大量日志文本输出。但大多数情况下,除了时间戳和一些次要标志之外,它会重复前一行,主要输出数据仅在几个小时内更改一次。我需要将此输出存储为文本文件以供将来处理/研究。为了仅打印每个 X 中的第一行,我应该将其通过管道传输到什么?
答案1
打印第一行并跳过每 N 行中的接下来的 N-1 行。
awk -v N=100 'NR%N==1' infile
测试:
$ seq 1000 |awk -v N=100 'NR%N==1'
1
101
201
301
401
....
要传递您想要跳过的行数,我们也可以从参数中读取该行数,因此:
$ seq 1000 |awk -v Num=100 -v Skip=98 '(NR-1)%Num<Num-Skip'
1
2
101
102
201
202
301
302
401
402
501
502
601
602
701
702
801
802
901
902
答案2
@αГsнιη已经向您展示了如何执行您所要求的操作(跳过特定行数),但听起来您可能最好不打印仅在“时间戳和一些次要标志”方面不同的后续行,而不是找出一个要跳过的具体行数。如果是这样,如果这些“时间戳和一些次要标志”存储在字段 3、6、8 和 17 中,您将如何执行此操作:
awk '
{
origRec = $0
$3=$6=$8=$17=""
currKey = $0
}
currKey != prevKey {
print origRec
prevKey = currKey
}
' file
您可以轻松地调整上面的内容,不仅打印每个相似组的第一行,还打印最后一行,这样您就可以看到第一个和最后一个时间戳(如果有用),和/或者您可以添加打印计数许多类似的行被跳过。
答案3
使用 GNU split
:
$ split -n r/1/100 input
seq
我们可以使用或 来测试jot
:
$ jot 500 | split -n r/1/100
$ seq 500 | split -n r/1/100
## 1
## 101
## 201
## 301
## 401
从
coreutils
:
r/k/n 同样,但仅输出k的第n到标准输出
-n r/1/100
每一百行中仅打印第一行。同样
-n r/2/100
将在每一百行中打印第二行。
我什么也没做,除了轻微地更改了命令答案。
和perl
:
$ perl -ne 'print if $_ % 100 == 1' input
这是 perl 命令,类似于中描述的命令这个答案。
答案4
seq 1000| awk -v x=1 'NR==x{print ; x=NR+100}'
输出
1
101
201
301
401
501
601
701
801
901