globular vs regex in find - regex

I am trying to find file names similar to this: fsimage_0000000000501205926
This is what I tried :
works: find . -name 'fsimage_???????????????????' -mtime -1
Following another SO post I tried this and it doesn't work:
find . -regextype posix-extended -regex '^fsimage_[0-9]{19}' -mtime -1
*** EDIT:
As suggested escaping the curly braces doesn't work either.
What I am doing wrong with the regex command ? I am using 4.4.2 GNU findutils.

You can use this regex in find:
find . -regextype posix-extended -regex '.*/fsimage_[0-9]{19}'
PS: If you're on OSX then use:
find -E . -regex '.*/fsimage_[0-9]{19}'

Related

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!

Unix - File Search with Regular expression

find . -iname "abc_v?_test.txt" -print
Which finds all the files
abc_v1_test.txt, abc_v2_test.txt, ..., abc_v9_test.txt
But how can I get additionally get abc_v10_test.txt, abc_v11_test.txt..
You can use -regex option as well:
find . -regextype posix-egrep -iregex ".*abc_v[0-9]{1,2}_test\.txt$"
You still have the option to get all files and pass them to grep, ack or ag:
find . | ag 'abc_v\d+_test\.txt'
note you can replace ag by egrep
Finally, I have implemented in this way
find . -iname "abc_v*_test.txt" -print.
is there any Regular expression that accepts only 1 or 2 numbers after V?

'find' using regex with variables

Please, help me with the following:
Let it be three files:
file-aaa.sh
file-bbb.sh
file-xxx.sh
In a bash script I have variables
$a=aaa
$b=bbb
Now, I want to execute something like:
find . -name "file-[$a|$b].sh"
and expect to get two files in output.
What am I doing wrong?
You can use this find:
find . -name "file-$a.sh" -o -name "file-$b.sh"
To combine it into one using -regex option:
On OSX:
find -E . -regex ".*file-($a|$b)\.txt"
On Linux:
find . -regextype posix-extended -regex ".*file-($a|$b)\.txt"

How to combine command substitution and regex?

Is there a possibility to do command substitution in a regex?
I want to find files in Linux with specific names. The name may include fix strings, but it may also only include the hostname.
So what i want to do is something like:
find /home/ -type f -regextype posix-extended -regex '.*(string1|string2|`hostname`).*'
I'm not sure whether it's possible to somehow concat the output of the hostname command with the regex?
Thanks in advance!
Try this :
find /home/ -type f -regextype posix-extended -regex ".*(string1|string2|$HOSTNAME).*"
if you need to use a command instead :
find /home/ -type f -regextype posix-extended -regex ".*(string1|string2|$(hostname)).*"

Regex to match logfiles 1 to 11

I would like to simply fetch logfiles 1 to 11 out of 500 with one regex:
log4j-cnode1.log.11
log4j-cnode1.log.10
log4j-cnode1.log.9
log4j-cnode1.log.8
log4j-cnode1.log.7
log4j-cnode1.log.6
log4j-cnode1.log.5
log4j-cnode1.log.4
log4j-cnode1.log.3
log4j-cnode1.log.2
log4j-cnode1.log.1
so I do not want to fetch log4j-cnode1.log.12, log4j-cnode1.log.13, ... , log4j-cnode1.log.500
I was trying this command:
find . -iname "log4j-cnode1*\.log\.(1[0-1]|[1-9])"
why does this not work?
1 to 9 works fine with this:
find . -iname "log4j-cnode1*\.log\.[1-9]"
Because -iname doesn't accept regular expressions, and even if it would, your 1* would probably not be what you want. Use -iregex:
find -regextype posix-extended -iregex '(.*/)?log4j-cnode1.*\.log\.(1[0-1]|[1-9])'
find . -iname "log4j-cnode1*\.log\.(1?[0-9])"
Your Regex says 1 followed by 0 or 1 followed by 1-9
$ find -name 'log4j-cnode1*\.log\.[0-9]*'
./log4j-cnode1.log.1
./log4j-cnode1.log.10
./log4j-cnode1.log.11
./log4j-cnode1.log.2
./log4j-cnode1.log.3
./log4j-cnode1.log.4
./log4j-cnode1.log.5
./log4j-cnode1.log.6
./log4j-cnode1.log.7
./log4j-cnode1.log.8
./log4j-cnode1.log.9
You got it almost right.
But, instead of -iname, use -iregex with -regextype egrep (or awk), like this:
find . -regextype egrep \
-iregex ".*log4j-cnode1.*\.log\.(1[0-1]|[1-9])"