How to test if string exists in file with Bash?

StringBashFile

String Problem Overview


I have a file that contains directory names:

my_list.txt :

/tmp
/var/tmp

I'd like to check in Bash before I'll add a directory name if that name already exists in the file.

String Solutions


Solution 1 - String

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.txt
then
    # code if found
else
    # code if not found
fi
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

Solution 2 - String

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.)

Solution 3 - String

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/bash

    declare 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" fi

    exit

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.

Solution 4 - String

Easiest and simplest way would be:

isInFile=$(cat file.txt | grep -c "string")


if [ $isInFile -eq 0 ]; then
   #string not contained in file
else
   #string is in file at least once
fi

grep -c will return the count of how many times the string occurs in the file.

Solution 5 - String

Simpler way:

if grep "$filename" my_list.txt > /dev/null
then
   ... found
else
   ... not found
fi

Tip: send to /dev/null if you want command's exit status, but not outputs.

Solution 6 - String

If I understood your question correctly, this should do what you need.

  1. you can specifiy the directory you would like to add through $check variable
  2. if the directory is already in the list, the output is "dir already listed"
  3. if the directory is not yet in the list, it is appended to my_list.txt

In one line: check="/tmp/newdirectory"; [[ -n $(grep "^$check\$" my_list.txt) ]] && echo "dir already listed" || echo "$check" >> my_list.txt

Solution 7 - String

grep -E "(string)" /path/to/file || echo "no match found"

-E option makes grep use regular expressions

Solution 8 - String

Here's a fast way to search and evaluate a string or partial string:

if grep -R "my-search-string" /my/file.ext
then
    # string exists
else
    # string not found
fi

You can also test first, if the command returns any results by running only:

grep -R "my-search-string" /my/file.ext

Solution 9 - String

The @Thomas's solution didn't work for me for some reason but I had longer string with special characters and whitespaces so I just changed the parameters like this:

if grep -Fxq 'string you want to find' "/path/to/file"; then
    echo "Found"
else
    echo "Not found"
fi

Hope it helps someone

Solution 10 - String

If you just want to check the existence of one line, you do not need to create a file. E.g.,

if grep -xq "LINE_TO_BE_MATCHED" FILE_TO_LOOK_IN ; then
  # code for if it exists
else
  # code for if it does not exist
fi  

Solution 11 - String

My version using fgrep

  FOUND=`fgrep -c "FOUND" $VALIDATION_FILE`
  if [ $FOUND -eq 0 ]; then
	echo "Not able to find"
  else
    echo "able to find" 	
  fi  

Solution 12 - String

I was looking for a way to do this in the terminal and filter lines in the normal "grep behaviour". Have your strings in a file strings.txt:

string1
string2
...

Then you can build a regular expression like (string1|string2|...) and use it for filtering:

cmd1 | grep -P "($(cat strings.txt | tr '\n' '|' | head -c -1))" | cmd2

Edit: Above only works if you don't use any regex characters, if escaping is required, it could be done like:

cat strings.txt | python3 -c "import re, sys; [sys.stdout.write(re.escape(line[:-1]) + '\n') for line in sys.stdin]" | ...

Solution 13 - String

A grep-less solution, works for me:

MY_LIST=$( cat /path/to/my_list.txt )



if [[ "${MY_LIST}" == *"${NEW_DIRECTORY_NAME}"* ]]; then
  echo "It's there!"
else
echo "its not there"
fi

based on: https://stackoverflow.com/a/229606/3306354

Solution 14 - String

grep -Fxq "String to be found" | ls -a
  • grep will helps you to check content
  • ls will list all the Files

Solution 15 - String

Slightly similar to other answers but does not fork cat and entries can contain spaces

contains() {
    [[ " ${list[@]} " =~ " ${1} " ]] && echo 'contains' || echo 'does not contain'
}

IFS=$'\r\n' list=($(<my_list.txt))

so, for a my_list.txt like

/tmp
/var/tmp
/Users/usr/dir with spaces

these tests

contains '/tmp'
contains '/bin'
contains '/var/tmp'
contains '/Users/usr/dir with spaces'
contains 'dir with spaces'

return

exists
does not exist
exists
exists
does not exist

Solution 16 - String

if grep -q "$Filename$" my_list.txt
   then
     echo "exist"
else 
     echo "not exist"
fi

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTorenView Question on Stackoverflow
Solution 1 - StringThomasView Answer on Stackoverflow
Solution 2 - StringKufView Answer on Stackoverflow
Solution 3 - StringLuca BorrioneView Answer on Stackoverflow
Solution 4 - StringChristian737View Answer on Stackoverflow
Solution 5 - StringimwilsonxuView Answer on Stackoverflow
Solution 6 - StringlecodesportifView Answer on Stackoverflow
Solution 7 - StringDavid OkwiiView Answer on Stackoverflow
Solution 8 - StringGTodorovView Answer on Stackoverflow
Solution 9 - StringB8ightYView Answer on Stackoverflow
Solution 10 - StringgordonView Answer on Stackoverflow
Solution 11 - StringRudyView Answer on Stackoverflow
Solution 12 - StringjnsView Answer on Stackoverflow
Solution 13 - StringAndrewDView Answer on Stackoverflow
Solution 14 - StringShinoy ShajiView Answer on Stackoverflow
Solution 15 - StringDiego Torres MilanoView Answer on Stackoverflow
Solution 16 - StringTriangleView Answer on Stackoverflow