0

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.

10
  • 3
    grep -Fx "$name" file Commented Feb 15, 2018 at 21:52
  • 1
    Now try grep -Fw "$name" file. And, don't just say "no luck." That's useless. Tell us exactly what happened: Was there an error? If so, show us the complete error message. Was there too much or too little output? If so, what exactly what was the output? Commented Feb 15, 2018 at 21:58
  • 1
    If grep -Fw "$name" produces output but grep -Fx "$name" file does not, that means that you have characters, invisible or otherwise, before or after flex in that line. If grep "$name$" file works for you, that means that those characters, visible or not, are before flex. Try running hexdump -C file and see what extra characters are on the flex line. Commented Feb 15, 2018 at 22:24
  • 1
    It sounds like the word you are looking for will always appear at the end of the line. In that case, try grep " $name$" file where there is a space before $name and, the final $ is the regex symbol for end-of-the-line. Commented Feb 15, 2018 at 23:50
  • 1
    No, that won't work. You wanted only whole word matches. Without the space in the regex, it will match aflex or bflex as well flex Commented Feb 16, 2018 at 0:03

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much. Great explanation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.