using shell variable in find regex - regex

i would like to delete files with some pattern(like start with 'test')that older than 1 day, i have:
mydir=/find/my/path
find $mydir -type f -mtime -1\
-regextype egrep -regex '$mydir\/test.*'\
-delete
but it did not delete files for me, i tried
mydir=/find/my/path
find $mydir -type f -mtime -1\
-regextype egrep -regex '.*\/test.*'\
-delete
this one works. Why did the first not work? according to
'find' using regex with variables
i can use variable in find regex, what's wrong?

It's because in the 1st one, you tried to evaluate a variable $mydir inside a single inverted comma with '$mydir\/test.*'. This won't evaluate the $mydir's value and will be taken literally as $mydir.
Use double inverted comma here and try again with
mydir=/find/my/path
find $mydir -type f -mtime -1\
-regextype egrep -regex "$mydir\/test.*"\
-delete

Gaganshera's answer already explains the the problems in your script and shows how to fix them. This is a different but equivalent solution combining find and globs:
mydir=/find/my/path
find "$mydir"/test* -type f -mtime -1 -delete

Related

Using regex OR with find to list and delete files

I have a folder with these files:
sample.jpg
sample.ods
sample.txt
sample.xlsx
Now, I need to find and remove files that end with either .ods or .xlsx.
To fish them out I initially use:
ls | grep -E "*.ods|*.xlsx"
This gives me:
sample.ods
sample.xlsx
Now, I don't want to parse ls so I use find:
find . -type f -regextype grep -regex '.*/*.ods\|*.xlsx' | wc -l
But that gives me the output of 1 while I expect to have 2 files before I extend the command to:
find . -type f -regextype grep -regex '.*/*.ods\|*.xlsx' | xargs -d"\n" rm
Which works but removes only the .ods file but not the .xlsx one.
What am I missing here?
I'm on ubuntu 18.04 and my find version is find (GNU findutils) 4.7.0-git.
You don't need to use regex here, just use -name and -or and so:
find . -type f -name "*.ods" -or -name "*.xlsx" -delete
Find files ending with either ods or xlsx and delete
If you really wanted to use regex, you could use the following:
find . -maxdepth 1 -regextype posix-extended -regex "(.*\.ods)|(.*\.xlsx)" -delete
Make sure that the expressions are in between brackets

RegEx for finding all files that start with any letter followed by a number

I am trying to make my bash script smart. I have some code that is doing a clean up of 10000's of files. What I am trying to work out is how can I find all files that have a bunch of letters a-z or A-Z in front of 0901*.*
find . -maxdepth 1 -type f -regextype posix-extended -regex '[a-z]\(0901).*'
find . -maxdepth 1 -type f -regextype posix-extended -regex '[a-z]*.*'
returns everything
while
find . -maxdepth 1 -type f -regextype posix-extended -regex '[a-z]\(0901).*'
returns nothing.
How do I solve this problem?
The following option should work with sed as the regex engine:
find . -maxdepth 1 -type f -regextype sed -regex "[A-Za-z]\+0901.*"
I am interpreting a bunch of letters as one or more letter, hence I used [A-Za-z]+ in front of the digits. You should not need parentheses here, but if you wanted to use them, you would have to escape those via backslash:
find . -maxdepth 1 -type f -regextype sed -regex "[A-Za-z]\+\(0901\).*"
With -regex returning the entire path (relatively as the case may be), need to take ./ into account. So, borrowing heavily from Tim's answer.
find . -maxdepth 1 -type f -regextype sed -regex '.*[A-Za-z]\+\(0901\).*'
I think you have to use this regex:
"[A-Za-z]0901"
Good Luck!

How to find files with regex and list them?

I am new to the whole command-line thing and trying to figure out how to search the current directory and its sub directories for files with a specific filename via regex. Then I want to have the files listed in my command-line.
The regex should match files like:
B2ctes_UCUAAwF-K-large-123x322-132x423.jpg
this_is-a-123-file_name-3124x2445-4235x32.jpeg
file-32x32-64x64.png
The important part is the -[number]x[number]-[number]x[number]
My attempt looks like this:
find . -type f -regex ".+?-\d+x\d+-\d+x\d+\.\w{3,4}" -ls;
There are two problems with this:
-ls puts shows a lot of information. I just want the filenames.
The regex doesn’t work. I have tried to use .+, but even that does not return anything.
You can use this find with regex:
find . -regextype posix-extended -type f -regex ".*-[[:digit:]]+x[[:digit:]]+-[[:digit:]]+x[[:digit:]]+\.[[:alnum:]]{3,4}"
Or on OSX:
find -E . -type f -regex ".*-[[:digit:]]+x[[:digit:]]+-[[:digit:]]+x[[:digit:]]+\.[[:alnum:]]{3,4}"
And without regex:
find . -type f -name "*-[[:digit:]]*x[[:digit:]]*-[[:digit:]]*x[[:digit:]]*.[[:alnum:]]*"
What about simply :
find . -type f -name '-[0-9]*x[0-9]*-[0-9]*x-[0-9]*'
or
find . -type f -regextype posix-egrep -regex '.*-[0-9]+x[0-9]+-[0-9]+x-[0-9]+.*'

Failing to match directories using find -regex

I have some directories under /var/log in the form of IP addresses i.e. 192.168.10.3
However the regex I have written is not matching them. Any clues?
find /var/log/ -type d -regex '/var/log/([0-9]+\.){3}[0-9]+'
Cheers.
Change your regex to,
find /var/log/ -type d -regextype sed -regex ".*/\([0-9]\{1,3\}\.\)\{3\}[0-9]\+"
OR
find /var/log/ -type d -regextype posix-egrep -regex ".*/([0-9]+.){3}[0-9]+"

Shell - How to deal with find -regex?

I need to look in a directory for sub-directories that all start by "course" but they have version next. For example
course1.1.0.0
course1.2.0.0
course1.3.0.0
So how should I modify my command to make it give me the right list of directories?
find test -regex "[course*]" -type d
You can do:
find test -type d -regex '.*/course[0-9.]*'
it will match files whose name is course plus an amount of numbers and dots.
For example:
$ ls course*
course1.23.0 course1.33.534.1 course1.a course1.a.2
$ find test -type d -regex '.*course[0-9.]*'
test/course1.33.534.1
test/course1.23.0
You need to remove the brackets, and use the proper wildcard syntax for regexes (.*):
find test -regex "course.*" -type d
You can also use the more familiar shell wildcard syntax, by using the -name option instead of -regex:
find test -name 'course*' -type d
I suggest using a regex for precise matching of version number sub directories:
find . -type d -iregex '^\./course\([0-9]\.\)*[0-9]$'
TESTING:
ls -d course*
course1.1.0.0 course1.1.0.5 course1.2.0.0 course1.txt
find . -type d -iregex '^\./course\([0-9]\.\)*[0-9]$'
./course1.1.0.0
./course1.1.0.5
./course1.2.0.0
UPDATE: To match [0-9]. exactly 3 times use this find command:
find test -type d -regex '.*/course[0-9]\.[0-9]\.[0-9]\.[0-9]$'