Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find all directories containing a file that contains a keyword in linux

In my hierarchy of directories I have many text files called STATUS.txt. These text files each contain one keyword such as COMPLETE, WAITING, FUTURE or OPEN. I wish to execute a shell command of the following form:

./mycommand OPEN

which will list all the directories that contain a file called STATUS.txt, where this file contains the text "OPEN"

In future I will want to extend this script so that the directories returned are sorted. Sorting will determined by a numeric value stored the file PRIORITY.txt, which lives in the same directories as STATUS.txt. However, this can wait until my competence level improves. For the time being I am happy to list the directories in any order.


I have searched Stack Overflow for the following, but to no avail:

  • unix filter by file contents
  • linux filter by file contents
  • shell traverse directory file contents
  • bash traverse directory file contents
  • shell traverse directory find
  • bash traverse directory find
  • linux file contents directory
  • unix file contents directory
  • linux find name contents
  • unix find name contents
  • shell read file show directory
  • bash read file show directory
  • bash directory search
  • shell directory search

I have tried the following shell commands:

This helps me identify all the directories that contain STATUS.txt

$ find ./ -name STATUS.txt

This reads STATUS.txt for every directory that contains it

$ find ./ -name STATUS.txt | xargs -I{} cat {}

This doesn't return any text, I was hoping it would return the name of each directory

$ find . -type d | while read d; do if [ -f STATUS.txt ]; then echo "${d}"; fi; done
like image 880
Insert name here Avatar asked Jul 14 '14 13:07

Insert name here


People also ask

How do I find all files containing specific text in Unix?

Without a doubt, grep is the best command to search a file (or files) for a specific text. By default, it returns all the lines of a file that contain a certain string. This behavior can be changed with the -l option, which instructs grep to only return the file names that contain the specified text.

How do you find a word in all files in a directory in Linux?

Search All Files in Directory To search all files in the current directory, use an asterisk instead of a filename at the end of a grep command. The output shows the name of the file with nix and returns the entire line.

How do I search all directories in Linux?

Using the Find Command The “find” command allows you to search for files for which you know the approximate filenames. The simplest form of the command searches for files in the current directory and recursively through its subdirectories that match the supplied search criteria.


2 Answers

... or the other way around:

find . -name "STATUS.txt" -exec grep -lF "OPEN" \{} +

If you want to wrap that in a script, a good starting point might be:

#!/bin/sh

[ $# -ne 1 ] && echo "One argument required" >&2 && exit 2
find . -name "STATUS.txt" -exec grep -lF "$1" \{} +

As pointed out by @BroSlow, if you are looking for directories containing the matching STATUS.txt files, this might be more what you are looking for:

fgrep --include='STATUS.txt' -rl 'OPEN' | xargs -L 1 dirname 

Or better

fgrep --include='STATUS.txt' -rl 'OPEN' |
           sed -e 's|^[^/]*$|./&|' -e 's|/[^/]*$||'
#              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#            simulate `xargs -L 1 dirname` using `sed`  
#      (no trailing `\`; returns `.` for path without dir part)                   
like image 55
Sylvain Leroux Avatar answered Oct 07 '22 02:10

Sylvain Leroux


Maybe you can try this:

grep -rl "OPEN" . --include='STATUS.txt'| sed 's/STATUS.txt//'

where grep -r means recursive , -l means only list the files matching, '.' is the directory location. You can pipe it to sed to remove the file name.

You can then wrap this in a bash script file where you can pass in keywords such as 'OPEN', 'FUTURE' as an argument.

#!/bin/bash
grep -rl "$1" . --include='STATUS.txt'| sed 's/STATUS.txt//'
like image 21
Wan Bachtiar Avatar answered Oct 07 '22 03:10

Wan Bachtiar