tags:

views:

268

answers:

3

Hi, I want to write a shell script to search and delete all non text files in a directory..

I basically cd into the directory that I want to iterate through in the script and search through all files.

-- Here is the part I can't do --

I want to check using an if statement if the file is a text file. If not I want to delete it else continue

Thanks

PS By the way this is in linux

EDIT

I assume a file is a "text file" if and only if its name matches the shell pattern *.txt.

+1  A: 

Use the opposite of, unless an if statement is mandatory:

find <dir-path> -type f -name "*.txt" -exec rm {} \;

What the opposite is exactly is an exercise for you. Hint: it comes before -name.

Your question was ambiguous about how you define a "text file", I assume it's just a file with extension ".txt" here.

Matthew Iselin
So yes, anything with a .txt. Sorry for not clarifying... I guess I tried using the commands but I kept getting arguments too long when I tried it. This is why I tried iterating through all the files and checking
webgoudarzi
Updated my answer with *correct* syntax (oops!) for -exec. There's still one thing missing from the command to find everything that *isn't* a .txt file, which a quick Google or man find will help you find.
Matthew Iselin
is it a ! before the name?
webgoudarzi
What does the man page say? (See the Operators section).
Matthew Iselin
+3  A: 

The file program always outputs the word "text" when passed the name of a file that it determines contains text format. You can test for output using grep. For example:

find -type f -exec file '{}' \; | grep -v '.*:[[:space:]].*text.*' | cut -d ':' -f 1

I strongly recommend printing out files to delete before deleting them, to the point of redirecting output to a file and then doing:

rm $(<filename)

after reviewing the contents of "filename". And beware of filenames with spaces, if you have those, things can get more involved.

Barry Kelly
+1 for the file cmd - as a better way to determine if a file is not a binary file
Wayne
rm $(<filename) will not work with all shells. It is more portable to do something like: while read f; do rm $f; done < filenames
William Pursell
Life is too short to suffer inferior tools in the name of portability when bash can be had everywhere it matters. In short: I don't give a damn.
Barry Kelly
So a (hypothetical) POSIX compliant shell which executes 100 times faster than bash and consumes a smaller memory footprint but fails to support this one trivial and mostly useless feature is 'inferior'? bash is not always available and not always desirable. A competent developer understands what code constructs artificially limit the usability of code, and avoids them when possible. This is one such instance.
William Pursell
If the script is too slow, I'll rewrite it in C or C# (mono also running on all the platforms I care about).
Barry Kelly
FWIW, if I had to deal with file spaces, I would do `while read -r f; do rm "$f"; done < filename`, but I wasn't, so I didn't.
Barry Kelly
Will you re-write all of your configure scripts in C? One of the main motivations for trying to make /bin/sh be dash on debian was to speed up configure runs. The tag for this question is 'scripting', not 'bash'. An answer that relies on a bashism should at least explictly mention that limitation.
William Pursell
I wouldn't touch autotools / autoconf with a 10 foot pole. This comment section is going nowhere though, consider it duly noted that I used a bashism and more portable alternatives have been mentioned.
Barry Kelly
+1  A: 
find . -type f ! -name "*.txt" -exec rm {} +;
ghostdog74