0

I am trying to write an awk script that can read a users input from command line and store it as a variable.

I know that if I compile from command line and do

./myawk.awk -v ID=4 text.sql

ID will be a variable set to 4. However, the input test cases I am given for my script are just

./myawk.awk ID=4 text.sql

The final goal of the script is to take an ID, find any line that begins with

-- ID

and print the following line. What I have so far is

#!/bin/awk -f
{
  if ($1 ~/--/ && $2 ~/^ID/){
    x = NR+1
  }
  while (NR <= x){
    print $0
  }
}

How would I able to read the variable ID without altering the line and adding -v before it, as well maybe give me advice on my current awk script.

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232

3 Answers3

3

If a variable assignment is given as a file operand on the command line of an awk script, that assignment will be carried out when awk gets to that point in using the file operands.

Example:

awk -f script.awk a=1 file1 file2 a=2 file3 a=3 file4

Here, the awk variable a will be set to 1 before reading file1. The variable will retain that value (unless it's changed by the awk program) until the file file2 has been read. It is then set to 2 etc.

This means that your command line properly sets the variable ID to 4 before reading text.sql.

The difference between -v ID=4 and this is that ID will not have been set in any BEGIN block. Using -v ID=4 sets ID to 4 and it will be available in BEGIN blocks.

Another issue with your code is that you use ID as a literal string in

if ($1 ~/--/ && $2 ~/^ID/){

That is, you test whether the second field starts with the string ID.

It also seems as if you expect your while loop to loop over the lines of the file. That line-by-line reading loop is already built into the way awk operates already and it very seldom needs to be explicit.

Instead,

$1 == "--" && $2 == ID { getline; print }

This will use string comparisons (not regular expression matches) to check whether the first whitespace-delimited field on the current line is the string -- and whether the second such field is the value of the variable ID. If so, the next line of input is read and printed.

To use regular expressions instead,

$0 ~ "^-- " ID "$" { getline; print }

This would match every line that starts with a double dash and a single space, followed by the value of ID and the end of the line ($ matches the end of the line). The line after the matching line would be printed.

Kusalananda
  • 333,661
0

Here's how to read user input with awk:

awk '
    BEGIN {
        printf "Enter an ID: "
        # "-" is the filename for stdin
        getline id < "-"
    }
    # then we can use that value however we like
    $1 == "--" && $2 == id {getline; print}
' file
glenn jackman
  • 85,964
-1
I Tried with below method and it worked fine


 #!/bin/bash
echo "enter the number"
read p
awk -v p="$p" '$1 == "--" && $2 == p {print $0}' filename