Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I can list all the textfiles (by mimetype) in a folder with:

find . -type f -print0 | xargs -0 file -i | fgrep -i text | sed 's/:$//g' 2>/dev/null | awk 'BEGIN {FS=": "} {print $1}'

Ok. But how can I add "fgrep" to this, to search in these files for "STRING" (regexp not needed, that's why fgrep).

this isn't good:

fgrep -iR "STRING" *

because it starts to search in ISO files, binary files too...

Fedora14/bash.

share|improve this question

2 Answers 2

up vote 7 down vote accepted

First, the grep: You can tell it not to search through binary files - use the -I switch - as manpage says:

-I     Process a binary  file  as  if  it  did  not  contain  matching data;
       this  is  equivalent  to  the --binary-files=without-match option.

Second, the find: To avoid using xargs and lots of piping, make use of the -exec test of find program. You can easily create a chain of logical tests using this: each consecutive -exec is performed if all the previous commands returned 0 (finished successfully).

share|improve this answer

That of @rozcietrzewiacz is a great solution, but if you still want to stay with text files (as returned by file), you can carefully build an array of file names, then execute your grep command on that array.

I suppose the following:

  • in no filename there is a newline (but spaces can be present);
  • a file util that support -0 and -i options;
  • GNU sed, or a sed supporting \x exadecimal char codes.

Here is an example

#!/bin/bash

get_file_list() {
  local path="$1"
  find "$path" -type f -exec file -0i {} + |
    sed -n '/\x00  *text\//s/\x00.*//p'
}

list=()
while IFS= read -r line; do
  list+=("$line")
done < <(get_file_list .)

# to choose options and pattern
grep -i pattern "${list[@]}"

The sed command take a sequence of line of text coming from file, composed from a filename, a NUL byte and the mime-type. If in the second part (after the NUL) there is the word text/ then remove that part and only print the filename, otherwise print nothing.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.