0

I am trying figure out how I can ask a user for input, use the input as the pattern to match with grep, and return the line number to a variable.

echo "What BCP do you want?"
read BCPid   # Get what value we're interested in.

for i in *.txt
do
  BCPlinenum=$(echo "$BCPid" | (grep -n "$BCPid" |cut -f1 -d:))
  echo "$BCPlinenum"
done

This returns a value of 1, regardless of what I input.

The file it searches looks as follows,

BCP C1 C2
BCP C1 C3
BCP C1 C4
BCP C2 C3
BCP C2 C4
BCP C3 C4

So, the desired function is to input "BCP C1 C2" and have it return 1 (the line number) to a variable.

Thank you!

2 Answers 2

2

You aren't actually feeding your input file into grep.

Change

BCPlinenum=$(echo "$BCPid" | (grep -n "$BCPid" |cut -f1 -d:))

to

BCPlinenum=$(grep -n -e "$BCPid" <"$i" | cut -f1 -d:)

or

BCPlinenum=$(grep -n -e "$BCPid" -- "$i" | cut -f1 -d:)
4
0

here it is, no loop required:

echo "What BCP do you want?"
read BCPid   # Get what value we're interested in.
results=`grep -nH "$BCPid" *.txt | cut -f1,2 -d:`

you can use a loop (or something better) to handle the output:

grep -nH "$BCPid" *.txt | cut -f1,2 -d: |
  while IFS=: read file n; do
    echo "found match in file $file on line $n"
  done
4
  • You might want while IFS=: read -r file n; otherwise, it'll be trying to split into variables on whitespace rather than colons (and backslashes in the names will potentially muck things up). And I do advise making it grep -n -e "$BCPid" -- *.txt -- which still isn't perfect, will fail with filenames with colons, but being able to correctly parse all possible filenames from grep's output unambiguously requires a grep with --null, which means a dependency on GNU tools which may not be desired. Commented May 19, 2016 at 19:56
  • oops, thanks. fixed the missing IFS. and thanks for the info about -e and --. if you'd like i can share a script that finds if anyone has named a file with a colon, leading dash, or space, and replaces the contents of those files with a stern admonishment ;)
    – webb
    Commented May 19, 2016 at 20:15
  • thinking about it further, even safer would be -- /dev/null *.txt -- otherwise, it'll behave badly if there's only one text file (doesn't print filenames if there's only one file passed, absent an explicit -H). Commented May 19, 2016 at 20:33
  • ...as for the stern-admonishment approach, to summarize my philosophy: You can't fix the world, you can only fix your code. (Pretend that you have the world you want instead of the world you actually do have, and you get bugs in the corners you conveniently ignored -- so better to take the realist's approach). Commented May 19, 2016 at 20:35

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.