find command search only non hidden directories - linux

In the following command i want to search only only the directories which are non hidden how can i do this using the following command .Iwant to ignore hidden directories while searching the log file
find /home/tom/project/ -name '.log.txt'
ls /home/tom/project/
dir1
dir2
.backup
.snapshot/
.ignore/

Try
find /home/tom/project -type d -name '.*' -prune -o -name .log.txt -print

This will find all files but ignore those that start with a dot so hidden files.
find /home/tom/project/ -type f \( -iname ".log.txt" ! -iname ".*" \)
EDIT:
If the above those not work, this should do the trick. It has a better regex.
find /home/tom/project/ \( ! -regex '.*/\..*' \) -type f -name ".log.txt"
EDIT2:
The following will exclude hidden folders but will search for the hidden files that have the requested pattern:
find /home/tom/project/ \( ! -regex '.*/\..*/..*' \) -type f -name ".log.txt"
EDIT3:
The grep solution :) if this doesn't work i'm lost :)
find /home/tom/project/ \( ! -regex '.*/\..*/..*' \) -exec grep -l ".log.txt" {} \;
EDIT4:
Have you tried the simple solutions?
find /home/tom/project/ -type f -name ".log.txt"
OR
find /home/tom/project/ -type f -name "*" -exec grep -l ".log.txt" {} \;

Related

How to remove files without certain extension?

How to remove all files without the .txt and .exe extensions recursively in the current working directory? I need a one-liner.
I tried:
find . ! -name "*.txt" "*.exe" -exec rm -r {} \
find -type f -regextype posix-extended -iregex '.*\.(txt|exe)$'
Try this.
find . -type f ! -name "*.exe" ! -name "*.txt" -exec rm {} \;
The above command will remove all the files other than the .exe and .txt extension files in the current directory and sub directory recursively.
If you have GNU find with the -delete action:
find . -type f ! \( -name '*.txt' -o -name '*.exe' \) -delete
And if not:
find . -type f ! \( -name '*.txt' -o -name '*.exe' \) -exec rm -f {} +
using -exec ... {} + to execute rm as few times as possible, with the arguments chained.
Try the following:
rm -f $(find . -type f ! \( -name "*.txt" -o -name "*.exe" \))
This will first recursively find all files that do not end with .txt or .exe extensions, and then delete all of these files.

FInd patternf for multiple pattern of files

I need to search for multiple pattern of files and check their mtime and if it morethan 30 days then delete all the files. I am using the below command but it's deleting only one pattern of file and not all. Kindly let me know where is the mistake in my command.
find /root -type f \( -name "*.tgz" -o -name "*.bz2" \) -mtime +30 -print -exec rm '{}' +
Try escaping parentheses in the command and adding a wildcard character:
find /root -type f \( -name "*.tgz" -o -name "*.bz2" \) -mtime +30 -exec rm {} \+

'Sed' not working on result of 'find' with multiple parameters

I'm trying to do a find and replace function, finding files which match a criteria then find/replace text within them.
Find statement (works find and returns list of files):
find / -type f -name "*.properties" -o -name "*.xml" -not \( -path '/tmp/*' -o -path '/var/tmp/*' \)
Sed find/replace:
sed -i 's/find/replace/g' {} \;
Putting together:
find / -type f -name "*.properties" -o -name "*.xml" -not \( -path '/tmp/*' -o -path '/var/tmp/*' \) -exec sed -i 's/10\.32\.19\.156/10.32.19.165/g' {} \;
However this does not seem to work. Removing some 'find' parameters causes it to work, for example this works:
find / -type f -name "*.properties" -exec sed -i 's/10\.32\.19\.156/10.32.19.165/g' {} \;
How can I get sed to work with the extended 'find' parameters?
Currently these two 'find' statements return exactly the same result in a test folder with only 2 files:
find /var/tmp/ipreplace/ -type f -name "*.properties"
find /var/tmp/ipreplace/ -type f -name "*.properties" -o -name "*.xml" -not \( -path '/tmp/*' -o -path '/var/tmp/*' \)
I guess the use of -path parameter in your find command is wrong.
Try the following:
find / -not \( -path '/tmp' -prune \) -not \( -path '/var/tmp' -prune \) -type f -name "*.properties" -o -name "*.xml" -exec sed -i 's/10\.32\.19\.156/10.32.19.165/g' {} \;
Look at this post for reference

cscope for files which are symlinks

I have a source directory with several files. Some of them are symlinks to other files.
I created a cscope.files file. But when I execute cscope. It complains for the files that are symlinks:
cscope: cannot find file /home/bla/source/file.cc
I think it's not very good, but maybe the correct way to go is to change the "find" script, to just write the destination of the symlink instead?
Currently I'm using:
# Write only the files which are NOT symlinks
find `pwd` \( \( -iname "*.c" -o -iname "*.cc" -o -iname "*.h" \) -and \( -not -type l \) \) -print > cscope.files
# Add the target of the symlink for all files matching the right extension, and are symlinks
find `pwd` \( \( -iname "*.c" -o -iname "*.cc" -o -iname "*.h" \) -and -type l \) -printf "%l\n" >> cscope.files
But this seems like a terrible solution. Still looking for a better one
I think you can use the command to find all real paths in a folder that you searched
find -L [your searched folder] -name [your searched pattern] -exec realpath {} \; >> cscope.files
For example, if I would like to add developed folder and linux kernel header to cscope.files, I will the these commands:
find -L `pwd` -iname "*.c" -o -iname "*.h" > cscope.files
find -L /usr/src/linux-headers-3.19.0-15-generic/ -iname '*.h' -exec realpath {} \; >> cscope.files
I hope the answer can help you.
For example if you want to give / as your path for cscope, and want cscope to search files with extensions .c/.h/.x/.s/.S you can give the find command as:
find / -type f -name "*.[chxsS]" -print -exec readlink -f {} \;> cscope.files
This will include regular files, including targets of symbolic links.
I just do the following to avoid symbolic links, as well get the absolute path in the cscope.files. With absolute path you can search from any directory in your sandbox when cscope is integrated with the vim editor
find /"path-to-your-sandbox" -path .git -prune -o -name "*.[ch]" -exec readlink -f {} \; > cscope.files
Note: if you omit -print from the find it does not put the symbolic link path in your cscope.files only the resolved path.
Better in a bash script:
#!/bin/bash
#
# find_cscope_files.sh
extension_list=(c cpp cxx cc h hpp hxx hh)
for x in "${extension_list[#]}"; do
find . -name "*.$x" -print -exec readlink -f {} \;
done
For reference for others I'm currently using.
find "$(pwd)" \( -name "*.[chCS]" -o -name "*.[ch][ci]" -o -name "*.[ch]pp" -o -name "*.[ch]++" -o -name "*.[ch]xx" ) -not \( -ipath "*unittest*" -or -ipath "*regress*" \) \( \( -type l -xtype f -exec readlink -f {} \; \) -o \( -type f -print \) \) >cscope.files
cscope -q -R -b -i cscope.files

find command how to combine OR and AND

I would like to find all php and js files inside a directory and exclude one of sub directory.
I may have to exclude more than one sub directory in the future.
I tried :
find /home/jul/here -type f -iname "*.php" -o -iname "*.js" ! -path "/home/jul/here/exclude/*"
Problem is that it is excluding only js file from /home/jul/here/exclude.
Is there a way to put some kind of parentheses?
find (something OR something else) AND exclude THIS
find /home/jul/here -type f \( -iname "*.php" -o -iname "*.js" \) ! -path "/home/jul/here/exclude/*"
You need to add the exclusion pattern after each group of files. So something like this should work:
find /home/jul/here -type f -iname "*.php" ! -path "/home/jul/here/exclude/*" -o -iname "*.js" ! -path "/home/jul/here/exclude/*"
Or maybe better with a variable:
EXCLUDE=/home/jul/here/exclude
find /home/jul/here -type f -iname "*.php" ! -path "$EXCLUDE/*" -o -iname "*.js" ! -path "$EXCLUDE/*"

Resources