如何使用 awk 命令重复列中的数字序列

如何使用 awk 命令重复列中的数字序列

我的输入文件包含这样的数据。

//address: 9050004 data: 1 id: 1 len: 0 size: 2
//address: 9050008 data: 1 id: 2 len: 0 size: 2
//address: 902e004 data: 1 id: 3 len: 0 size: 2
...
//address: 902e008 data: 1 id: 799 len: 0 size: 2
//address: 9096004 data: 1 id: 800 len: 0 size: 2
//address: 9096008 data: 1 id: 801 len: 0 size: 2
//address: 9097004 data: 1 id: 802 len: 0 size: 2
...
//address: 902e008 data: 1 id: 1599 len: 0 size: 2
//address: 9096004 data: 1 id: 1600 len: 0 size: 2
//address: 9096008 data: 1 id: 1601 len: 0 size: 2
//address: 9097004 data: 1 id: 1602 len: 0 size: 2

从上面的数据来看,id值不应超过 800。序列必须重复,如 1,2,...799,1,2...799。

所以我的输出应该如下所示

//address: 9050004 data: 1 id: 1 len: 0 size: 2
//address: 9050008 data: 1 id: 2 len: 0 size: 2
//address: 902e004 data: 1 id: 3 len: 0 size: 2
...
//address: 902e008 data: 1 id: 799 len: 0 size: 2
//address: 9096004 data: 1 id: 1 len: 0 size: 2
//address: 9096008 data: 1 id: 2 len: 0 size: 2
//address: 9097004 data: 1 id: 3 len: 0 size: 2
...
//address: 902e008 data: 1 id: 799 len: 0 size: 2
//address: 9096004 data: 1 id: 1 len: 0 size: 2
//address: 9096008 data: 1 id: 2 len: 0 size: 2
//address: 9097004 data: 1 id: 3 len: 0 size: 2

有人可以帮我在 awk 命令中获取上述命令吗?

答案1

要在达到 800 时回滚到 1,您必须将该列重新计算为((id - 1) % 799) + 1,其中%是模运算符:

$ awk '/^\/\// { $6 = (($6 - 1) % 799) + 1; print }' file
//address: 9050004 data: 1 id: 1 len: 0 size: 2
//address: 9050008 data: 1 id: 2 len: 0 size: 2
//address: 902e004 data: 1 id: 3 len: 0 size: 2
//address: 902e008 data: 1 id: 799 len: 0 size: 2
//address: 9096004 data: 1 id: 1 len: 0 size: 2
//address: 9096008 data: 1 id: 2 len: 0 size: 2
//address: 9097004 data: 1 id: 3 len: 0 size: 2
//address: 902e008 data: 1 id: 1 len: 0 size: 2
//address: 9096004 data: 1 id: 2 len: 0 size: 2
//address: 9096008 data: 1 id: 3 len: 0 size: 2
//address: 9097004 data: 1 id: 4 len: 0 size: 2

请注意,在您的预期输出中,idfor 地址902e008为 799。如果您将范围限制为 [1, 799],则这是不可能的。

答案2

这对我有用

awk 'BEGIN{FS=OFS=" "}{i++;if (i<5) {$6=i} else {i=0};print}' aa.txt

只需将 i<5 更改为 i<800

测试:

$ cat aa.txt
//address: 9050004 data: 1 id: 1 len: 0 size: 2
//address: 9050008 data: 1 id: 2 len: 0 size: 2
//address: 902e004 data: 1 id: 3 len: 0 size: 2
//address: 9050004 data: 1 id: 4 len: 0 size: 2
//address: 9050008 data: 1 id: 5 len: 0 size: 2
//address: 902e004 data: 1 id: 6 len: 0 size: 2

$ awk 'BEGIN{FS=OFS=" "}{i++;if (i<5) {$6=i} else {i=0};print}' aa.txt
//address: 9050004 data: 1 id: 1 len: 0 size: 2
//address: 9050008 data: 1 id: 2 len: 0 size: 2
//address: 902e004 data: 1 id: 3 len: 0 size: 2
//address: 9050004 data: 1 id: 4 len: 0 size: 2
//address: 9050004 data: 1 id: 5 len: 0 size: 2
//address: 902e004 data: 1 id: 1 len: 0 size: 2

答案3

@Kusalananda 的 Perl 变体:

perl -pE 's/id: *\K(\d+)/($1-1)%799+1/e'

(数字与 PO 示例不完全相符)

相关内容