Here is a simplified version with an extended explanation for beginners like me who are trying to learn how to add more than one command on a single line.
If you were to write out the problem step by step, it would look like this:
// For every file in this directory // Check the filetype // If it an ASCII file, then print out the filename
For this we can use three UNIX commands: find , file and grep .
find checks every file in the directory.
file will give us the file type. In our case, we are looking for ASCII text return
grep will search for the keyword "ASCII" in the output of file
So how can we combine them into one line? There are several ways to do this, but I believe that doing it in the order of our pseudo-code makes sense (especially for a beginner like me).
find ./ -exec file {} ";" | grep 'ASCII'
It looks complicated, but not bad when we break it:
find ./ = browse all files in this directory. The find displays the file name of any file that matches the "expression", or whatever comes after the path, which in our case is the current directory or ./
The most important thing to understand is that everything after the first bit will be evaluated as True or False. If True, the file name will be printed. If not, the command proceeds.
-exec = this flag is an option in the find command, which allows us to use the result of some other command as a search expression. It is like calling a function inside a function.
file {} = command called inside find . The file command returns a string indicating the type of file. Regularly, it will look like this: file mytextfile.txt . In our case, we want it to use any file that is searched by the find , so we insert curly braces {} as an empty variable or parameter. In other words, we simply ask the system to print a line for each file in the directory.
";" = this is required by find and is the punctuation mark at the end of our -exec command. See the manual for "find" for details if you need it by running man find .
| grep 'ASCII' | grep 'ASCII' = | - this is a pipe. The pipe will output the output from what's on the left and use it as an input to what's on the right. It takes the output of the find (a string that is a file type for a single file) and checks if it contains the string 'ASCII' . If so, it returns true.
NOW, the expression to the right of find ./ will return true when the grep returns true. Voila.