GNU/Linux / Finding files – WhyNotWiki

Ethan Caldwell Blog

< GNU/Linux

Finding all files that aren’t named __

Say you want a list of all files and directories that are not named .svn

You might think that the command to do this would simply be:

> find . \( -type d -name .svn -prune \)

But that pretty much does the exact opposite of what you want (why?). So even though you said -prune, it actually did the equivalent of find . -name .svn!:

rails_root> find . \( -type d -name .svn -prune \)
./public/javascripts/.svn
./public/.svn
./public/stylesheets/.svn
./public/images/.svn

Weird.

Instead, you apparently need to or it with an action, such as -print or -exec

rails_root> find . \( -type d -name .svn -prune \) -o -exec echo {} \;
rails_root> find . \( -type d -name .svn -prune \) -o -print
.
./public
./public/dispatch.cgi
./public/javascripts
./public/javascripts/prototype.js
./public/javascripts/effects.js
./public/javascripts/dragdrop.js
./public/javascripts/controls.js
./public/javascripts/application.js
./public/favicon.ico
./public/index.html
./public/404.html
./public/robots.txt
./public/500.html
./public/dispatch.fcgi
./public/stylesheets
./public/.htaccess
./public/images
./public/images/rails.png
./public/dispatch.rb

Finding files based on modified date

Files modified today (0 days ago), ordered by date:

$ sudo find . -ctime 0 -printf "%AT %p\n" | sort | nosvn
09:28:43 ./.bash_history
09:44:12 ./.psql_history
10:29:01 ./public_html/logs/db_errors.log
10:29:01 ./public_html/logs/frontend.log
10:29:01 ./public_html/logs/test.log
10:29:01 ./public_html/logs/tests.log
14:09:07 ./.viminfo
14:25:28 ./devNotInRepo.tgz
14:40:55 ./.lesshst
14:41:38 .
14:41:38 ./data/faxes/tmp_attach
14:41:38 ./data/faxes/to_send
14:41:39 ./bin

Files modified today in the 12:00 hour.

$ sudo find ~anthony -ctime 0 -printf "%AT %p\n" | grep "^12:" | grep -v svn

Find files larger than a certain minimum size

> # Find files bigger than 10,000 KB :
> find / -xdev -size +10000k -exec du --megabytes {} \;
26      /var/lib/slocate/slocate.db
13      /var/lib/rpm/Packages

Find all files that have CRLF line endings

> find . \( -type d -name .svn -prune \) -o -exec file {} \; | grep CRLF
./init.rb: ASCII text, with CRLF line terminators

Now that you’ve found all of those files, what if you wanted to convert them to Unix format (LF)?

Unfortunately, there’s no easy way (that I know of) to take the output from the previous command and pipe it to another command which will convert it for you.

Why is this? Well, because the text output by file that comes after the filename (ASCII text, with CRLF line terminators, for instance, will itself be interpreted as filenames by any program we pipe this output into. Demonstration:

> find . \( -type d -name .svn -prune \) -o -exec file {} \; | grep CRLF | xargs -n1 echo
./init.rb:
ASCII
text,
with
CRLF
line
terminators

None of those are valid filenames, actually. So it would do no good for us to construct this command:

> find . \( -type d -name .svn -prune \) -o -exec file {} \; | grep CRLF | xargs -n1 dos2unix

How would we construct a command like that that worked then?

Well, we could write a Ruby script to do it…

...

Or we could put a [sed (category)] command in the command pipe chain…

> find . \( -type d -name .svn -prune \) -o -exec file {} \; | grep CRLF | sed -e 's/^\(.*\): .*$/\1/g' | xargs -n1 dos2unix

Or we could use another filter program that filters out just the filename part… (http://svn.tylerrick.com/public/shell/bin/filename)

> find . \( -type d -name .svn -prune \) -o -exec file {} \; | grep CRLF | filename | xargs -n1 dos2unix

Or we can just convert the individually files manually:

> dos2unix init.rb
dos2unix: converting file init.rb to UNIX format ...

Finding files that all hard links to a file

http://erik.thauvin.net/wiki/pages/viewpage.action?pageId=67. Retrieved on 2007-05-11 11:18.

Hardlink files are identified by the second field of a long list. For example:

> ls -l
total 4
-rw-r-r-    1 erik     erik            1 Feb 16 02:07 test
> ln test test2
> ls -l
total 8
-rw-r-r-    2 erik     erik            1 Feb 16 02:07 test
-rw-r-r-    2 erik     erik            1 Feb 16 02:07 test2

Notice field 2 changed from 1 to 2 indicating that a hard link has been created. There are now 2 filenames pointing to the same data.

To list all hardlinked files in the current directory:

> find . ! -type d -links +1 -ls | sort -n
 18587    4 -rw-r-r-   2 erik     erik            1 Feb 16 02:07 ./test
 18587    4 -rw-r-r-   2 erik     erik            1 Feb 16 02:07 ./test2

Note: Use: ls -i to also list directories.

To find all hardlink to the same inode:

> find / -xdev -inum 18587
/home/erik/test/test
/home/erik/test/test2

Note: Hardlinks have to be located on the same file system, use df . to determine the current filesystem.