2

My input file contains data like this.

//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

from the above data, id value should not cross 800. The sequence must be repeated like 1,2,...799,1,2...799.

so my output should be like below

//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

Could someone please help me in getting the above one in awk command?

4

To wrap back to 1 when reaching 800, you will have to recalculate that column as ((id - 1) % 799) + 1, where % is the modulus operator:

$ 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

Note that in your expected output, the id for address 902e008 is 799. This is not possible if you're restricting the range to [1, 799].

  • Why we need the modulus operator to reset counting...? What i miss ? – George Vasiliou Feb 14 '17 at 19:51
  • @GeorgeVasiliou You don't need to use the modulus operator if the IDs are strictly increasing with +1 on every line. I don't know if that's the case though, so I'm playing it safe and modify the ID based on the existing ID. If the file is re-sorted on, say, the address field, then this solution would still assign the same new IDs to the same address lines. – Kusalananda Feb 14 '17 at 19:58
2

This worked for me

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

just change i<5 with i<800

Testing:

$ 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
0

Perl variant of @Kusalananda:

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

(numbers don't fit exactly with PO example)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.