tags:

views:

104

answers:

5

This is my final script

find -regex "^\..*[^(~$|\.o$|\.exe)]" | grep -v "\.svn" | grep -v ".tab." | grep  -v ".yy." | xargs svn add 2>/dev/null

For testing i dont want to add it to svn so i use

find -regex "^\..*[^(~$|\.o$|\.exe)]" | grep -v "\.svn" | grep -v ".tab." | grep  -v ".yy."

NOTE: I wanted to ignore files that started with '.' (in current and subfolders) but couldnt figure out how so i settled for .svn

I tried removing the extra greps to produce one regex but for the life of me i couldnt get it to ignore .svn (or .FILE) in current and sub folders and i couldnt get it to ignore .tab. or .yy.

One problem is i couldnt understand how to make ^. (ignore if start with?) work. I'm sure one problem is the fact i do .* which will ignore my .tab. rule and i am not sure how to get around.

+1  A: 

You can tell find to ignore certain folders and their contents with -prune. And you don't need a regular expression here, the other find commands are completely sufficient. If you want to be able to handle file names with spaces, I would further use -print0. Summing up, this should do what you need:

find . \( -name ".*" -prune \) -or \
    -name "*.exe" -or -name "*.o" -or -name "*~" \
    -print0 | xargs -0 svn add
soulmerge
find also supports ! for not, and most versions support "-not" as a synonym (but it's not POSIX).
Jefromi
A: 

I'm not 100% sure what you want to achieve but find -regex '^.*/[^.].*' should work (matches any non-dot character at the start of the name).

Aaron Digulla
This isn't going to do what you want. There are only two required characters to get a match - the `/[^.]`. It'll match anything that contains a non-hidden file anywhere in the path, not just in the last component of the path (e.g. /home/username/.svn will match).
Jefromi
@Jefromi: Doesn't return anything for me.
Aaron Digulla
+2  A: 

NOTE: I wanted to ignore files that started with '.' (in current and subfolders) but couldnt figure out how so i settled for .svn

One problem is i couldnt understand how to make ^. (ignore if start with?) work. I'm sure one problem is the fact i do .* which will ignore my .tab. rule and i am not sure how to get around.

The -regex test on find is applied to the full path, not just the filename. From the man page:

For example, to match a file named './fubar3', you can use the regular expression '.bar.' or '.b.3', but not 'f.r3'.

soulmerge's answer provides one way to get all your conditions into the find statement; you could also do it with something like

find * -regex 'include-pattern' -a ! \( -regex 'exclude-pattern' [-o 'exclude-pattern2' ...] \)

If you want to combine multiple patterns to exclude, whether in your piped greps or in find's regexes, just use an or:

grep -v '\.svn\|.tab.\|.yy.'
egrep -v '\.svn|.tab.|.yy.'

Note that it's a very, very good idea to use single quotes for regex - you don't want any $ to attempt variable expansion.

Edit: Those exclude patterns you're suggesting really don't need to be regex. You can get them just with -name, which matches only the actual name, not the whole path.

find * -regex 'include-pattern' -a ! \( -name .svn -o -name "*tab*" \)
Jefromi
You should replace `\|` in your grep example with `|\`
Aaron Digulla
No, that's part of extended regular expressions. I added an egrep line using that.
Jefromi
+3  A: 

Your root problem is that you think you can do this:

[^(~$|\.o$|\.exe)]

You can't.

In a character class (that's what you have here) you can include (or exclude) individual characters, but you can't write expressions there. The above is equivalent (as far as the regex engine is concerned) to:

[^()~$|.oex]

I'm on Windows, so I can't give you a tested command, and your post leaves me a little bit puzzled which files you actually want. So this is meant as an indication into the right direction regarding your regex misconception.

Tomalak
I suspect in this case regex is totally unnecessary. As I belatedly noted in my answer, you can just use -name. Something like `find * ! \( -name *.o -o -name *.exe -o ...\)`, I expect.
Jefromi
I also think `find` can do it without regex. I'm not very familiar with it, but I saw the major regex error the OP made.
Tomalak
@Tomalak - yep, you're definitely right about that one. I saw "final script" and mistakenly skimmed over the initial inclusive regex to the ones the OP was explicitly asking about. Good catch.
Jefromi
A: 

Grep supports multiple patterns. E.g.:

grep -v -e "\.svn" -e ".tab." -e ".yy."
Mr.Ree