2

I have a file /tmp/a.txt with following content:

1
2
3
4
5

Using AWK, I want to prompt user to specify a range in any of the following formats and print the matching lines.

comma separated

1,2,3

space separated

1 2 3

and in range using -

1-3

Expected Output:

1
2
3

Below is the sample awk command to capture input from user, what should I put here to get the required output.

 awk 'BEGIN { printf "Enter the range: " ; getline name < "-" }{?}' /tmp/a.txt
  • Why don't you apply what you learned from your other thread? – RudiC Aug 27 '18 at 8:37
  • yes, that one is for bash , wanted to get it in AWK, trying to get it done using substr function etc.. also wanted to see how other people could do it easily with AWK. – Bharat Aug 27 '18 at 8:49
0

You can use this awk command:

awk 'BEGIN { printf "Enter the range: " ; getline r < "-"; split(r,a,"[ ,]")} \
  {for (i in a){split(a[i],b,"-"); if(a[i]==NR||(b[2]!=""&&b[1]<=NR&&b[2]>=NR)){print}}}' file

Explanation:

  • printf "Enter the range: " ; getline r < "-"; copied from the question (to read the user input into the variable r)
  • split(r,a,"[ ,]") split the input at delimiters space and comma and write them into array a.
  • for (i in a) For each line awk processes, it loops trough the array a
    • split(a[i],b,"-") each element in a is splitted again at the delimiter - and the range is then saved in array b.
    • if(a[i]==NR||(b[2]!=""&&b[1]<=NR&&b[2]>=NR)) if the line number awk is currently processing is in array a or if the line number is between the two numbers in array b...
      • {print} ... print the line.

You can also use combined input like

1-3,4 5 7-13
1

You can achieve not exactly what you want but similar to with something like:

awk -vnums="$Userinput" 'nums ~ "\\<"NR"\\>"' infile

It will not check what character numbers are delimited and don't understand the range accordingly, but works nice, maybe you can extend this to recognize and expand the ranges to the exact numbers then print (I give this part to you).

testing:

Userinput='4-53,5  0'; awk -F'[-  ]' -vnums="$Userinput" 'nums ~ "\\<"NR"\\>"' infile
4
5
0

It's not quite clear if you want the line No.s (NR) to match the ranges entered, or the entire line's ($0), or the first field's ($1) values... Try

awk '
BEGIN   {printf "Enter the range: "
         getline ANS < "/dev/tty"
         for (n=split (ANS, T, "[ ,]"); n; n--) {for (m=split (T[n], R, "-"); m; m--)   TGT[R[m]]
                                                 for (i=R[1]+1; i<R[2]; i++)            TGT[i]
                                                }
        }
$1 in TGT
' file
Enter the range: 1-3
1
2
3

and change $1 to $0 or NR.

  • it is failing for some specific input values e.g Enter the range: 1,3 5-6 Output: 1 2 3 4 5 6 – Bharat Aug 27 '18 at 12:20
  • Corrected - error was in the lower limit of the last for loop. – RudiC Aug 27 '18 at 12:45

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.