Tursko
Tursko

Reputation: 132

Finding exact string in a file using a variable (grep)

I am writing a script currently that is searching inside a txt file.

So basically I have a loop that grabs a name from a txt file and then searches for that name in another file (file2), but I am having issues.

name=flex

grep $name file2 > file2output

So if file2 (file I am searching inside of) has something like

    1 flex-inside

    2 flex

    1 flex-end

It will match all three of those when I only want it to match the exact string flex.

I want it to only match

2 flex

I was trying to do something where it would look for whatever is in $name and then \n. But nothing is working.

Thank you for the help.

Upvotes: 0

Views: 1760

Answers (1)

John1024
John1024

Reputation: 113814

As per the comments, the input file looks like:

$ cat file2
    1 flex-inside
    3 reflex
    2 flex
    1 flex-end

We want to select the line matching flex but not reflex or flex-end, etc. In that case, try:

$ name='flex'
$ grep " $name$" file2
    2 flex

There are two key points here:

  1. There is a space before $name to assure that words like reflex are not matched.

  2. There is a dollar sign, $, after $name to require that flex occurs at the end of the line.

Extended version: handling embedded spaces

The above all assumes that the matched text after the numbers does not include spaces. Consider for example the input file:

$ cat file2
    1 flex inside
    3 re flex
    2 flex
    1 flexible

We can select the one line matching flex with:

$ grep -E "^[[:space:]]*[[:digit:]]+[[:space:]]+$name$" file2
    2 flex

Here, ^[[:space:]]*[[:digit:]]+[[:space:]]+ matches zero or more spaces that begin the line followed by digits followed by one or more spaces. This is followed by $name$ which matches $name appearing at the end ($) of the line.

The use of character classes like [:space:] and [:digit:] assures that this code is unicode safe.

Upvotes: 1

Related Questions