11

I can't figure this out. I need to look at every line in a file and check whether it matches a word that is given in a variable.

I started with command read, but I don't know what I am supposed to use after that. I tried grep, but I probably used it wrongly.

while read line; do 
  if [ $condition  ] ;then echo "ok" fi
done < file.txt
0

4 Answers 4

9

Here's a quickie for you, simply what we're doing is

Line 1: While reading file into variable line

Line 2: Match a regex, echo the $line if matching the word "bird" echo that line. Do whatever actions you need here, in this if statement.

Line 3: End of while loop, which pipes in the file foo.text

#!/bin/bash
while read line; do
  if [[ $line =~ bird ]] ; then echo $line; fi
done <foo.text

Note that "bird" is a regex. So that you could replace it with for example: bird.*word to match the same line with a regular expression.

Try it with a file like so, called foo.text with the contents:

my dog is brown
her cat is white
the bird is the word
3
  • What exactly means ^$ ? I undetstand that it is some kind of regex, but when I replace it with my own word and own txt file it doesn't work
    – applenic
    Mar 17, 2015 at 20:36
  • ^anything$ means "match the beginning and end of line", ^ is beginning, and $ means end. so that the whole line is "anything". If you want a partial match like you have a line that says "my dog is brown" and you just want to match dog, get rid of the ^ and $, and just have "dog" there. (edited code to reflect a simplification in regex)
    – dougBTV
    Mar 17, 2015 at 20:57
  • If you don't intend to do any processing for each line, you should just use grep and skip using read entirely.
    – Sildoreth
    Feb 8, 2023 at 16:47
6

The easier way to do this, is using grep (or egrep).

grep bird file.txt
0
0

Here's a simple script that passes in two arguments (filename and variable)... There's also a hardcoded version beneath that.

#!/bin/bash

[ $# -lt 2 ] && echo "wrong number of args" && exit 1
file=$1
var=$2
while read line; do
    if  echo "$line" | grep -q "$var"; then echo "ok"; fi
done < "$file"
exit 0

[user@myserver ~]$ myscript file.txt some_text

Alternatively, if you prefer to hardcode the file (and variable) rather than passing in as an arguments...

while read line; do
    if  echo "$line" | grep -q "some_text"; then echo "ok"; fi
done < file.txt
0

Depending on what processing you want to do for each line, sed is another option. I'd only recommend it if you already intend to use sed on each line, though.

sed -n '/regex/p' foo.text

I'm using sed's -n option to suppress normal output. And I'm using the p command to print only the matching lines.

You could combine this with editing commands, too (the processing I was referring to).

sed -n '/regex/{s/pattern/replacement/;p}' foo.text

If you don't want to do any processing on each line, then I agree with steviethecat's answer that grep is the best solution, being the cleanest and fastest.

grep regex foo.text

If you want to do processing that requires additional Unix commands, then (and only then) do I recommend using read.

1
  • 1
    Downvote with no comment!? This is a legitimate technique. The fact that the OP is trying to use read instead of just grep and that the accepted answer does not use grep implies that they want to do some kind of processing on each line.
    – Sildoreth
    Feb 8, 2023 at 16:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .