How to use Awk in this situation

2019-09-21 03:04发布

问题:

how to change this file

335
339
666665
666668

to this result

335
336
337
338
339
666665
666666
666667
666668

explain : between two numbers with the same long, it will push the missed number to make numeric ascending order .Many Thanks

回答1:

I believe this does what you want.

awk 'alen==length($1) {for (i=a;i<=$1;i++) print i}; {a=$1; alen=length(a); if (a==(i-1)) {a++}}'

When alen (the length of a) is the same as the length of the current line loop between a and $1 printing out all missing values.

Then set a to the new $1, alen to the length of a, and when we dealt with a missing range (when a is the same as i - 1) increment a so we don't duplicate that number (this handles cases of sequential lines like 335, 339, 350 without duplicating 339).

With credit to @fedorqui for the basic idea.

Edit: I believe this fixes the problem I noted in the comments (which I think is what @JohnB was indicating as well):

awk '{f=0; if (alen==length($1)) {for (i=a;i<=$1;i++) print i} else {f=1}} {a=$1; alen=length(a)} a==(i-1){a++} f{print; a++}'

I feel like there should be a simpler way to do that but I don't see it at the moment.

Edit again: The input file I ended up testing with:

335
339
340
345
3412
34125
666665
666668


回答2:

The first approach is this:

$ awk 'NR%2 {a=$1; next} $1>a {for (i=a;i<=$1;i++) print i}' file
335
336
337
338
339
666665
666666
666667
666668

It can be improved as much as info and effort you put in your question :)

Explanation

  • NR%2 {a=$1; next} as NR stands for number of record (number of line in this case), NR%2 is 1 if NR is not multiple of 2. So this stores the value of the line in the variable a in the odd lines. Then, next stops processing current line.
  • $1>a {for (i=a;i<=$1;i++) print i} in the other cases (even lines), if the value is bigger than the one that was stored, it loops from that value up to the current one, printing all the values in between.