Linux find ignore directory with grep

I tried to use this as guide for linux find ignore directory with grep but I am unable to figure out what I am doing wrong.

I would like to grep through all my files for scp but ignore dir2, dir3, and dir4.

find /dir1 -type d ( -path ./dir2 -o -path ./dir3 -o -path ./dir4 ) -prune -o -type f -exec grep -i "scp" {} + 2>/dev/null

The website is removing my backslashes when I copy from my computer to the website.

find /dir1 -type d \( -path ./dir2 -o -path ./dir3 -o -path ./dir4 \) -prune -o -type f -exec grep -i "scp" {} + 2>/dev/null

find /dir1 -type d \( -path ./dir2 -o -path ./dir3 -o -path ./dir4 \) -prune -o -type f -exec grep -i "scp" {} + 2>/dev/null

first of all, you need to "back-slash"/escape both parenthesis: \( and \)...

The website is removing my backslashes when I copy from my computer to the website.

find /dir1 -type d \( -path ./dir2 -o -path ./dir3 -o -path ./dir4 \) -prune -o -type f -exec grep -i "scp" {} + 2>/dev/null

find /dir1 -type d \( -path ./dir2 -o -path ./dir3 -o -path ./dir4 \) -prune -o -type f -exec grep -i "scp" {} + 2>/dev/null

Your start directory is /dir1
so -path ./dir2 won't match. But -path /dir1/dir2 would (if it exists).

Alternatively, cd first:

cd /dir1 && find .  ...

and -path ./dir2 will match.

A minor improvement is -exec grep -i "scp" /dev/null {} + so the filename is even printed if there is one matching file. Certain grep versions take -exec grep -Hi "scp" {} + and you don't need the /dev/null trick.

I hope this copies correctly. I tried with the . in front of the path and without. I also moved the /dev/null . That did not make a difference. Neither of these methods are ignoring the /home/local/develop directories.

find /home/local/ -type d \( -path ./home/local/develop -o -path ./home/local/develop2 -o -path ./home/local/develop3 \) -prune -o -type f -exec grep -i "scp" 2>/dev/null {} +
find /home/local/ -type d\ ( -path /home/local/develop -o -path /home/local/develop2 -o -path /home/local/develop3 \) -prune -o -type f -exec grep -i "scp" 2>/dev/null {} +

I saw this and it looked promising.

find -name "*.js" -not -path "*/omitme/*"

So I tried this. This didn’t seem to do anything but change the order of the output. I did see it was picking up binary files.

find /home/local/ -not -path "./develop/*" -type f -exec grep -i "scp" + 2>/dev/null {} +

So I did this to get rid of binary files. At this point the output was easier to read. I saw js files were taking up most of my output.

find /home/local/ -not -path "./develop/*" -type f -exec grep -Ii "scp" + 2>/dev/null {} +

So I did this to get rid of the js files output. Then I noticed develop was not going away.

find /home/local/ -not -path "./develop/*" -type f -exec grep -Ii "scp" + 2>/dev/null {} + | grep -v js

So I did this to get rid of develop directory.

find /home/local/ -not -path "./develop/*" -type f -exec grep -Ii "scp" + 2>/dev/null {} + | grep -v js | grep -v develop

This also works.

grep -rI "scp" . | grep -v js | grep -v develop

It must be -exec grep -i "scp" /dev/null {} +
so grep sees another file /dev/null in addition to the collected files from {}
It will never find anything in /dev/null, but if there is only one collected file it will print its filename because it got the /dev/null as another file.

The alternative is -exec grep -Hi "scp" {} +
-Hi is short for -H -i
-H is: always print the filename even if there is only one file.

2>/dev/null at the very of the find command is something else. It means: suppress all error messages. (And this is done by the calling shell; the find command does not see it.)

If the starting point is /something then it will match /something but never ./something