Linux find -type f ignored - linux

I'm creating a cron job, that will find all *.log* files (it will be used to remove them later, when it works).
The find command looks like this:
find /data/dg \( -path /data/dg/kf/data -o -path /data/dg/pg/data \) -prune -o -name "*.log*" -type f
And it should find all files with name ".log" that are not in directories /data/dg/kf/data and /data/dg/pg/data
However the output this command gives contains also the directories.
...
/data/dg/kf/log/controller.log.2019-09-08-22
/data/dg/kf/log/server.log.2019-09-09-07
/data/dg/kf/data
/data/dg/pg/log/postgresql-2019-09-27_000000.log
/data/dg/pg/log/postgresql-2019-09-27_100859.log
/data/dg/pg/log/postgresql-2019-09-27_102411.log
/data/dg/pg/data
/data/dg/sim/log/sim_2019-09-27-11.0.log
/data/dg/sim/log/sim_2019-09-27-12.0.log
...
It seems that -type f doesn't work. What's wrong?

put -type f right after /data/dg
find /data/dg -type f -not -path "/data/dg/kf/data*" -not -path "/data/dg/pg/data*" -name "*.log*"

Related

How to Find Recent or Today’s Modified Files in Linux

I have a requirement that will have to find out latest modified files list along with date and time.
mainly we have 2 files that boot.properties and ldap related files as part of beadmin password change activity.
find /target_directory -type f -name "*boot.properties" -exec ls -ltr {} \;
is giving only boot.properties but I need to find other files which is in different location.
find supports multiple path arguments, so you could do something like
find /target_dir /other -type f \( -name "*boot.properties" -o -name "other*" \) -exec ls -ltr {} +
try something like this if you have different location and file names.
find /root_directory \
\( \( \
-path "/target_directory1/*" -type f -name "*boot.properties" \) -o \( \
-path "/target_directory2/*" -type f -name "*boot2.properties" \
\) \) -exec ls -ltr {} \;
also, you have other options to find by modified date too.
check this article
https://www.cyberciti.biz/faq/linux-unix-osxfind-files-by-date/

Exclude list of file extensions from find in bash shell

I want to write a cleanup routine for my make file that removes every thing except the necessary source files in my folder. For example, my folder contains files with the following extensions: .f .f90 .F90 .F03 .o .h .out .dat .txt .hdf .gif.
I know I can accomplish this with:
find . -name \( '*.o' '*.out' '*.dat' '*.txt' '*.hdf' '*.gif' \) -delete
Using negation, I can do this:
find . -not -name '*.f*' -not -name '*.F*' -not -name '*.h' -delete
But, when I try to do this:
find . -not -name \( '*.f*' '*.F*' '*.h' \)
I get an error:
find: paths must exceed expression: [first expression in the above list]
(In this case, I would get:
find: paths must exceed expression: *.f*
)
Can you explain why this happens, and how to do what I am trying to do? I just hate writing -not -name every time I want to add a file extension to the list. Also, I want to find out why this is giving me an error so that I can learn Linux better.
Thanks!
find . -not -name \( '*.f' '*.F' '*.h' \)
is interpreted as
find
. # path to search
-not # negate next expression
-name \( # expression for files named "("
'*.f' '*.F' .'*.h' \) # more paths to search?
leading to the error.
Since these are single-letter extensions, you can collapse them to a single glob:
find . -not -name '*.[fFh]'
but if they are longer, you have to write out the globs
find . -not -name '*.f' -not -name '*.F' -not -name '*.h'
or
find . -not \( -name '*.f' -o -name '*.F' -o -name '*.h' \)
or switch to using regular expressions.
find . -not -regex '.*\.(f|F|h)$'
Note that regular expressions in find is not part of the POSIX standard and might not be available in all implementations.

How to exclude multiple subdirectories when using "find" command?

I was looking for "*.py" files, and exclude both "build" and "bin" directories. I used this command:
find * -path "build" -prune -path "bin" -prune -o -type f \( -name "*.py" \) -print > findpyfiles.txt
The "findpyfiles.txt" still contains results started with "bin/".
How to fix it?
Although the question has an answer elsewhere, it may be worth knowing why your command didn't work right: You omitted an operator between -path "build" -prune and -path "bin" -prune, and -and is assumed where the operator is omitted, thus the -path "bin" is not evaluated when -path "build" returns false. Explicitly specifying the OR operator fixes it, either
find * -path build -prune -o -path bin -prune -o -type f -name "*.py" -print >findpyfiles.txt
or
find * \( -path build -o -path bin \) -prune -o -type f -name "*.py" -print >findpyfiles.txt

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/*"

excluding a directory from find and sed rename

I'm using this command to go through all files, directories and subdirectories to change any mentions of oldurl.com to newurl.org:
find . -type f -name '*.php' -exec sed -i 's|oldurl.com|newurl.org|g' {} +
It works fine, however, I need to exclude three sub-directories from ANY CHANGES: /cache, /archive and /etc as changing the urls with the above command in these paths breaks other scripts.
Haven't had much luck finding an answer... Is it even possible?
Many thanks for any suggestions/help.
Use finds -not Option:
find . -type f -name '*.php' -not \( -path './etc/*' -o -path './cache/*' -o -path './archive/*' \) -exec sed -i 's|oldurl.com|newurl.org|g' {} \;

Resources