0

I'm trying to display the line number of the first 'string' occurrence from a long string variable and set the result to another variable.

To display the line of the first 'string" occurrence, I use:

grep -n -m 1 String Filename.csv | cut -f1 -d:

It works fine. However, I would like to get the 'String' value from the array variable and Filename.csv switch to the long string. For example:

string[0]='Column2'

Query="Select Column1,
              Column2,
              Column3
       From   dual"

And now:

Line_number=$(grep -n -m 1 ${string[0]} "$Query" | cut -f1 -d:)
echo $Line_number

The result should be: 2

But it displays:

grep: "Select Column1,
                  Column2,
                  Column3
           From   dual  "   No such file or directory

What's wrong?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
andreww
  • 223
  • 6
  • 16
  • Am extra `(` in `$((grep -n -m 1 ${string[0]} "$Query" |cut -f1 -d:)` ? – sjsam Jul 11 '16 at 12:43
  • You are trying to read the content of Query as filenames, use `<<< "$Query"` – 123 Jul 11 '16 at 12:53
  • The canonical is *[How do I set a variable to the output of a command in Bash?](https://stackoverflow.com/questions/4651437)*. Despite the unspecific title, it covers the case of ***(variable) input to the external command*** (in a (Bash) variable. But is this question sufficiently different? – Peter Mortensen Nov 10 '20 at 01:05

2 Answers2

0

Change the script to:

string[0]='Column2'

Query="Select Column1,\n
              Column2,\n
              Column3\n
       From   dual"

Line_number=$(echo $Query | grep -n -m 1 ${string[0]} |cut -f1 -d:)
echo $Line_number

And see what you will get.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
sel-fish
  • 4,308
  • 2
  • 20
  • 39
  • Hi, There is no error, but result is all the time 1 (seems to be all in one line), I put \n but I got an error with invalid character (from database) – andreww Jul 11 '16 at 13:02
  • @maciek2791 you shouldn't use grep like "grep $pattern $Query" where Query is not the filename but a string, only "echo $Query |grep $pattern" is available. ```man grep``` to see the detail. – sel-fish Jul 11 '16 at 13:25
  • Can you describe the changes and/or the gist/idea of the solution (so every reader does not have to run diff)? You can [edit your answer](https://stackoverflow.com/posts/38307414/edit) (but ***without*** "Update:", "Edit:", or similar). – Peter Mortensen Nov 10 '20 at 00:05
  • Re *"And see what you will get."*: Did it work for you? – Peter Mortensen Nov 10 '20 at 01:04
0

The AWK solution for this would be:

arr=$(echo "${string[@]}")
line_number=$(awk -v var="$arr" '$0 ~ var{print NR;exit 0}' <<<"$Query")
echo "$line_number"

What is happening here?

  • We can't directly pass a Bash array to AWK, so we echoed it and store it in arr.
  • var="$arr" stores the shell variable to AWK variable var.
  • $0 ~ var{print NR;exit 0} checks(~) for the pattern, prints the line number of the first occurrence and exit the script.
  • <<< in Bash is called here-string which helps you pass strings to commands.

The sed solution for this would be:

arr=$(echo "${string[@]}")
line_number=$(sed -n "/$arr/{=;q}" <<<"$Query")
echo "$line_number"

What is happening here?

  • We can't directly pass a bash array to sed, so we echoed it and stored it in arr.
  • -n option suppresses the normal output.
  • /$arr/{=;q} checks for the pattern(/stuff/), print the line number(=) and then quits(q) sed.
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
sjsam
  • 21,411
  • 5
  • 55
  • 102