tags:

views:

102

answers:

5

I'm trying to find files modified recently with this

find . -mtime 0

Which gives me

en/content/file.xml
es/file.php
en/file.php.swp
css/main.css
js/main.js

But I'd like to filter out the en and es directories but would like to grab anything else. In addition, I'd like to filter out .swp files from the results of those.

So I want to get back:

css/main.css
js/main.js
xml/foo.xml

In addition to every other file not within es/en and not ending in .swp

+2  A: 
find . -mtime 0 | grep -v '^en' | grep -v '^es' | grep -v .swp

The -v flag for grep makes it return all lines that don't match the pattern.

speshak
This might not work correctly: The output of `find .` will return lines that starts with `./` and thus the `grep -v "^e..." will not match, and thus will not filter the unwanted lines.
Chen Levy
+2  A: 

Try this:

find . -mtime 0 | grep -v '^en' | grep -v '^es'

Adding the cap character at the beginning of the pattern given to grep ensures that it is a must to find the pattern at the start of the line.

Update: Following Chen Levy's comment(s), use the following instead of the above

find . -mtime 0 | grep -v '^\./en' | grep -v '^\./es'

find is great but the implementation in various UNIX versions differs, so I prefer solutions that are easier to memorize and using commands with more standard options

mmonem
Anchoring the patterns do make it a little more robust. I updated my answer to match.
speshak
Please see my comment for @speshak's answer. Also find can do this work without the help of grep.
Chen Levy
@Chen, absolutely right! I updated my answer.
mmonem
You are almost there. Note that `.` is significant in a regex, try `\.` instead, and then you can revert to your initial answer of matching beginning of line with `^\./es`.
Chen Levy
+8  A: 

properly, just in find:

find -mtime 0 -not \( -name '*.swp' -o -path './es*' -o -path './en*' \)
mvds
Good answer! find is great but the implementation in various UNIX versions differs, so I prefer solutions that are easier to memorize and using more commands with standard options
mmonem
I can agree with that, but looking at the OP's tags and rep I figured `grep` was known and not an option. Keeping it within `find` allows for way more flexible output/actions (`-exec`, `-ls`, `-print0`, `-printf`, ...)
mvds
(btw the tag `bash` implies GNU)
mvds
-exec -ls -print are very well known and personally I used them in AIX with almost no difference. My point is: it is hard to memorize the 'little bit' complex matching and modifiers options of find command while other simple and easy to memorize options exist.
mmonem
+3  A: 

The -prune command prevents find form descending down the directories you wish to avoid:

find . \( -name en -o -name es \) -prune , -mtime 0 ! -name "*.swp"
Chen Levy
A: 

The -regex option of find(1) (which can be combined with the -E option to enable extended regular expressions) matches the whole file path as well.

find . -mtime 0 -not \( -name '*.swp' -o -regex '\./es.*' -o -regex '\./en.*' \)
find "$(pwd -P)" -mtime 0 -not \( -name '*.swp' -o -regex '.*/es.*' -o -regex '.*/en.*' \)
karl