'find' using regex with variables - regex

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"

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

pattern to match multiple filenames with find utility

How to find multiple filenames with the bash find command?
$ find /path/* -type f -name pattern
The pattern should match a list of file names:
fname1.jpg
fname2.png
myfile.css
example.gif
I tryed with
https://alvinalexander.com/linux-unix/linux-find-multiple-filenames-patterns-command-example
find multiple filenames command: finding three filename extensions
find . -type f \( -name "*cache" -o -name "*xml" -o -name "*html" \)
and it works.
Anyway I think it would be cleaner with a -name pattern, rather than with a list of -names.
from
$ man find
-name pattern
I m searching for something like: -name '[fname2.png|myfile.css|example.gif ]'
-regex alternative would look as follows:
find . -type f -regextype posix-egrep -regex ".+\.(jpg|png|css)$"
As for -name option:
-name pattern - Base of file name (the path with the leading
directories removed) matches shell pattern.
Shell pattern is not a full-fledged regex pattern.
Just mix them:
find -name "aoc*" -regextype awk -regex ".*[0-9].(class|scala)"
This searches for files, matching shell-pattern aoc* and end in number, with ending .class or .scala.
For your example:
find -name "fname*" -regextype awk -regex ".*[0-9].(png|jpg|css)"
Available types are listet with:
find -regextype -help
However, I first tried "-regextype sed" which is available, but sed itself has options, changing the styles of regexes. And patterns I used to use with sed didn't work, but since the pattern works with awk, it's sufficient for me.

globular vs regex in find

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}'

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]+.*'

find all files except e.g. *.xml files in shell

Using bash, how to find files in a directory structure except for *.xml files?
I'm just trying to use
find . -regex ....
regexe:
'.*^((?!xml).)*$'
but without expected results...
or is there another way to achieve this, i.e. without a regexp matching?
find . ! -name "*.xml" -type f
find . -not -name '*.xml'
Should do the trick.
Sloppier than the find solutions above, and it does more work than it needs to, but you could do
find . | grep -v '\.xml$'
Also, is this a tree of source code? Maybe you have all your source code and some XML in a tree, but you want to only get the source code? If you were using ack, you could do:
ack -f --noxml
with bash:
shopt -s extglob globstar nullglob
for f in **/*!(.xml); do
[[ -d $f ]] && continue
# do stuff with $f
done
You can also do it with or-ring as follows:
find . -type f -name "*.xml" -o -type f -print
Try something like this for a regex solution:
find . -regextype posix-extended -not -regex '^.*\.xml$'