How to test if string exists in file with Bash? How to test if string exists in file with Bash? bash bash

How to test if string exists in file with Bash?


grep -Fxq "$FILENAME" my_list.txt

The exit status is 0 (true) if the name was found, 1 (false) if not, so:

if grep -Fxq "$FILENAME" my_list.txtthen    # code if foundelse    # code if not foundfi

Explanation

Here are the relevant sections of the man page for grep:

grep [options] PATTERN [FILE...]

-F, --fixed-strings

        Interpret PATTERN as a list of fixed strings, separated by newlines, any of which is to be matched.

-x, --line-regexp

        Select only those matches that exactly match the whole line.

-q, --quiet, --silent

        Quiet; do not write anything to standard output. Exit immediately with zero status if any match is found, even if an error was detected. Also see the -s or --no-messages option.

Error handling

As rightfully pointed out in the comments, the above approach silently treats error cases as if the string was found. If you want to handle errors in a different way, you'll have to omit the -q option, and detect errors based on the exit status:

Normally, the exit status is 0 if selected lines are found and 1 otherwise. But the exit status is 2 if an error occurred, unless the -q or --quiet or --silent option is used and a selected line is found. Note, however, that POSIX only mandates, for programs such as grep, cmp, and diff, that the exit status in case of error be greater than 1; it is therefore advisable, for the sake of portability, to use logic that tests for this general condition instead of strict equality with 2.

To suppress the normal output from grep, you can redirect it to /dev/null. Note that standard error remains undirected, so any error messages that grep might print will end up on the console as you'd probably want.

To handle the three cases, we can use a case statement:

case `grep -Fx "$FILENAME" "$LIST" >/dev/null; echo $?` in  0)    # code if found    ;;  1)    # code if not found    ;;  *)    # code if an error occurred    ;;esac


Regarding the following solution:

grep -Fxq "$FILENAME" my_list.txt

In case you are wondering (as I did) what -Fxq means in plain English:

  • F: Affects how PATTERN is interpreted (fixed string instead of a regex)
  • x: Match whole line
  • q: Shhhhh... minimal printing

From the man file:

-F, --fixed-strings    Interpret  PATTERN  as  a  list of fixed strings, separated by newlines, any of which is to be matched.    (-F is specified by POSIX.)-x, --line-regexp    Select only those matches that exactly match the whole line.  (-x is specified by POSIX.)-q, --quiet, --silent    Quiet; do not write anything to standard output.  Exit immediately with zero status  if  any  match  is          found,  even  if  an error was detected.  Also see the -s or --no-messages option.  (-q is specified by          POSIX.)


Three methods in my mind:

1) Short test for a name in a path (I'm not sure this might be your case)

ls -a "path" | grep "name"


2) Short test for a string in a file

grep -R "string" "filepath"


3) Longer bash script using regex:

#!/bin/bashdeclare file="content.txt"declare regex="\s+string\s+"declare file_content=$( cat "${file}" )if [[ " $file_content " =~ $regex ]] # please note the space before and after the file content    then        echo "found"    else        echo "not found"fiexit

This should be quicker if you have to test multiple string on a file content using a loop for example changing the regex at any cicle.