[lug] "find" question
Tkil
tkil at scrye.com
Wed Aug 18 01:16:51 MDT 2004
>>>>> "Daniel" == Daniel Webb <lists at danielwebb.us> writes:
Daniel> Aha! I'm embarassed, but I didn't even know about the -xtype option.
Daniel> Here's the command I wanted all along:
Daniel> find . -follow \( -type f -a \! -xtype l \)
Just btw, I think that you can drop the parens and the "-a"; "and" is
implied between two conjoined clauses, and since there's nothing to
nest, you don't need the parens. So it should be the same as:
find . -follow -type f \! -xtype l
In fact, bash isn't nearly as twitchy as csh is about the naked bang,
either:
find . -follow -type f ! -xtype l
One thing I did notice, though, is that this can return the same file
multiple times (if it gets there through different paths / links).
Using the same simple hierarchy I set up in my last message, I got:
| $ find . -follow -type f ! -xtype l
| ./a/foo
| ./b/bar
| ./b/baz
| ./c/bar
| ./c/baz
(This does successfully ignore ./a/lbar, which is a symlink to a file)
Not sure if there is a cheap way to get rid of duplicates. 'find' has
to keep track of uniqueness internally, typically with dev/inode
tuples, but I couldn't find a way to make it do it for me, so I
resorted to this gross hack:
| $ find . -follow -type f ! -xtype l \
| -exec readlink --canonicalize '{}' \; | \
| sort | uniq | sed -e "s@^$PWD at .@"
| ./a/foo
| ./b/bar
| ./b/baz
Oooh, I forgot about "-i" to 'ls'. If we know all these files are on
the same filesystem, we can use that to uniquify the results,
hopefully more cheaply than by canonicalizing symlink paths... but I
can't think of a short way to compare only the first field of the
output. Huh. So I haul out the swiss army chainsaw again:
| $ find . -follow -type f ! -xtype l -print0 | \
| xargs -0 ls -1i --quoting-style=shell | \
| perl -lne '($inode,$rest) = split " ", $_, 2;
| print $rest unless $seen{$inode}++'
| ./a/foo
| './b/bad name'
| ./b/bar
| ./b/baz
(I added "b/bad name", yes with a space in it, to test the quoting /
wordsep capabilities of my pipeline... seems to have worked.)
Daniel> Rephrased, what I want to accomplish is:
Daniel> List all non-link files in a directory tree. Directory
Daniel> symbolic links should be followed.
Daniel> -xtype solves the problem I was having when only using -type.
Daniel> GNU tools are the best!
Yeah. The non-standardness can occasionally be a pain, but GNU/Linux
is rapidly becoming its own standard. So.
Happy hacking,
t.
More information about the LUG
mailing list