Regular expression - Find ocurrences that has one string - linux

Im trying to find all files modified during de last 24 hours in /var/www/vhost directory.
That is working ok with the find command, then, I want to filter the list because i don't want jpg files, jpeg files and so on.
Now i have this and it's working ok:
find /var/www/vhosts/ -ctime 0 -type f | grep -ve ".jpg$" | grep -ve ".jpeg"
I guess (and know) there's a better solution to my problem.
Any help?

change your find command itself to
find /var/www/vhosts/ -not \( -name "*.jpeg" -o -name "*.jpg" \) -ctime 0 -type f

You can do it all with one find command:
find /var/www/vhosts -ctime 0 -type f \! -iname \*.jpg \! -iname \*.jpeg

Use -regex and ! (negation):
find $DIR -regextype posix-extended ! -regex '.*\.(gif|jpg|pdf|png)$'

Related

Problems with understanding and combining linux terminal commands

First one :
We found several files and we have to copy that to kat4 and here is code, but it doesn't seem to work corectly
find /home/imk-prac/ -type f -size -13c -name '*\?plik\?*' -exec cp {} /home/inf-19/aduda/\*kat1\*/\*kat2\*/\*kat4\*/ \; 2> /dev/null
'cp' I assume that it is copy, but I don't know what 'exec' and '{}' do.
Second one:
find /home/imk-prac/ \( -type f -size -13c -name '*\?plik\?*' \) -o\( -type d -name '\[Kolo1\]*' \)2> /dev/null
Generally,I understand this line (except for '2' and '-o') , but I want to add looking for files which were modificated in less that 30 days and here is what I wanted to combine with upper command :
find /home/imk-prac/ -type f -mtime -30 -exec ls -l {} \; > /dev/null
As a result I wrote it down as:
find /home/imk-prac/ \( -type f -size -13c -name '*\?plik\?' -mtime -30 -exec ls -l{}\) -o \( -type d -name '\[Kolo1\]*' \) 2> /dev/null
but it doesn't work
Moreover, I wanted to add looking for files with speciefied quantity of symbols and I found this command:
grep -Po '(^|\s)\S{64}(\s|$)' file
But I have no idea how to combine all of those 3 upper commands.
I will be grateful for any help, thank you for your time!

How to use -regex in the find command on Linux command line

The objective is to find and list anything with "messages" and/or "error.log" etc.. in the beginning then list both "messages.1..99" and "error.log.1..99" using regular expressions.
This command works for however, it would require me to make many -or searches, but to simplify, I would like to have multiple in a set within the search. Like for instance:
# find /var/log -maxdepth 1 -type f -size +1M -name [messages|error.log|secure.log|kern.log...]?[0-9]|[0-9][0-9] ! -iname "*.gz"
not
# find /var/log -maxdepth 1 -type f -size +1M -name "messages?[0-9]" -o -name "messages?[0-9][0-9]"
How might I perform this command with regular expressions?
# find /var/log -maxdepth 1 -type f -size +1M -name "[messages,error.log,kern,secure]?[0-9]" ! -iname "*.gz"
My attempt with regex doesn't print anything in standard out:
# find /var/log -maxdepth 1 -type f -size +1M -regex -name "[messages,error,kern,secure]?[0-9]" ! -iname "*.gz"
Try this:
find /var/log -maxdepth 1 -type f -size +1M -type f -regextype egrep -regex '.*(messages|error|kern|secure)\.[0-9]+.*' -not -name \*gz

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 {} \+

Using "find … -delete" to remove image files only from special subdirectories

I need to clean up some subdirectories inside my music collection from unwanted images. I’m using Ubuntu 14.04 and/or Linux Mint 17.2 and a bash shell script using the find command.
The directory structure (minimal example) is as follows:
Tagged
Artist #1
Artist #1 - An Album
Artist #1 - A Track.flac
cover.jpg
something.png
Artist #1 - [compilations]
Artist #1 - A Track.flac
cover.jpg
something.png
Artist #2
Artist #2 - Another Album
Artist #2 - A Track.mp3
cover.jpg
Only in the subfolders ending with "[compilations]", I want to delete all kind of jpeg and/or png images (because the tagging software erroneously puts them there). Any images that happen to be in normal "album" folders I wish too keep.
With my directory structure, folders with "[compilations]" in the name can only happen just below the "Artist" folders, repectively; so a maximum of two levels deep.
I came up with the following find command:
$ cd Tagged
$ find . -maxdepth 2 -type d -name '*\[compilations\]' -exec find {} -type f -iname '*.jp*g' -or -iname '*.png' -delete \;
This seems to do something and takes a while, but the files "./Artist #1/Artist #1 - [compilations]/cover.jpg" and "./Artist #1/Artist #1 - [compilations]/something.png" are still there (and all other image files).
Being quite new to Linux, I assume I make a dumb mistake using find's -delete option, because the following command (without -delete) shows the files correctly:
$ find . -maxdepth 2 -type d -name '*\[compilations\]' -exec find {} -type f -iname '*.jp*g' -or -iname '*.png' \;
./Artist #1/Artist #1 - [compilations]/cover.jpg
./Artist #1/Artist #1 - [compilations]/something.png
So here are my questions:
Why does the -delete not work?
Is this command really safe regarding "extravaganza" like whitespace, glob characters and foreign characters in the paths and filenames?
How would I have to rewrite the above command, still using bash and find?
Could the command be optimized (re speed, safety, nested finds)?
In the actual collection, the command must traverse 16899 folders, almost all of them contain whitespace and foreign characters (like Czech, Russian, Japanese, Greek, German …), so it must be robust.
Thanks in advance for any insights and some enlightenment!
Your -delete predicate only applies to the
-iname '*.png'
predicate, because you missed groupings: when you give find the following:
-type f -iname '*.jp*g' -or -iname '*.png' -delete
because of the precedence of the boolean operators, find understands:
\( -type f -iname '*.jp*g' \) -or \( -iname '*.png' -delete \)
To fix this, use:
-type f \( -iname '*.jp*g' -or -iname '*.png' \) -delete
I'd suggest that to experiment you replace -delete with -print: you'll see what the -delete applies to!
Now, regarding your nested find: because of the structure of your directory tree (your files are only in depth 3), you should be able to do with only one instance of find:
find -maxdepth 3 -path '*/*\[compilations\]/*' \( -iname '*.jp*g' -o -iname '*.png' \) -type f -print
(I put -print instead of -delete so that you can check the command before executing it with -delete).
After some experimentation, I think my error was in not putting the OR'ed part in parentheses—it seems find used the -delete only on the right part of the last OR, i.e., tried to delete '*.png'. Alas, almost all of my cover images were '*.jpg' so I thought it wouldn't work at all!
So I think the corrected command should be:
$ find . -depth -maxdepth 2 -type d -name '*\[compilations\]' -exec find {} -type f \( -iname '*.jp*g' -or -iname '*.png' \) -delete \;
It seems to work correctly on my test case above.
Nevertheless, some confirmation would be nice. An maybe some answers to my other questions, just for information and learning. Thank you!

find command search only non hidden directories

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" {} \;

Resources