Ubuntu: Print the content of the first file which contains some specific strings



Question:

I'm searching for a command that prints the contents of the first file found in /etc that contains a string 10.17.1 or 130.236.189 where the commands needed to be used are: find, grep, head, xargs, and cat.

What I reached before Ravexina's answer and with some help was something like the below.

sudo egrep â€"rl '(10.17.1|130.236.189)' /etc | head -1 | cat  


Solution:1

I would go with this:

grep  -lRE  '10.17.1|130.236.189' /etc/ | head -1 | xargs cat  
  • grep is used with -R to search /etc recursively while using -E to use extended grep features.
  • The -l switch with grep is used to print only the file names instead of content.
  • Then pipe it to xargs and xargs feed the file name as parameter tor cat
  • After all cat will print it out.

If you have to use find:

find /etc/ 2> /dev/null | xargs grep -lE '10.17.1|130.236.189' 2> /dev/null | head -1 | xargs cat  

I used 2> /dev/null to ignore permission errors, when I'm a regular user, If you are using sudo, there is no need to use them ;)


Solution:2

I think you could avoid the head and xargs by using the exit status of grep as a logical predicate in the find command e.g.

find /etc -type f -exec grep -IFq -e '10.17.1' -e '130.236.189' {} \; -exec cat {} \; -quit  

Explanation of the grep flags:

  • -I ignore binary files (usually don't want to be grepping those)
  • -F treat the patterns as fixed strings rather than regular expressions (avoids the need to escape the periods - at the expense of not being able to use the regex | operator)
  • -q exit immediately with zero status if any match is found

The first file in which grep finds a match will cause it to exit with zero status, which in turn will cause find to execute the cat on that file. Assuming the cat is successful, find will then quit so that only the contents of the first matching file are printed.


Solution:3

Here's what I'd do:

$ find -type f -exec bash -c 'grep -q "10\.17\.1\|130\.236\.189" "$1" && printf "\n>>> $1\n" && cat "$1"' sh {} \;  

The way this works is basically like so:

  • we let find handle locating files ( -type f) and for each one of them executing a command using -exec ... {}\; flag
  • that specific command will be in form bash -c 'command1;command2' arg1 arg2
  • each file that is found is passed as argument to bash -c and within the command itself it is refereed to as $1 variable
  • grep -q will quietly check file for basic regular expression 10\.17\.1\|130\.236\.189 and exit with 0 if text is found or 1 if not found.
  • upon successful finding of the text we print file name using printf command, and then cat the file.

Test run:

$ find -type f -exec bash -c 'grep -q "10\.17\.1\|130\.236\.189" "$1" && printf "\n>>> $1\n" && cat "$1"' sh {} \;    >>> ./somefile.txt  10.17.1  some other text  >>> ./somefile2.txt  another file, 130.236.189  some other text  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »