- regex match either string in linux «find» command
- Regular Expression in Find command
- 2 Answers 2
- Using Find Command With Regex
- Quick Introduction to Regex Tokens
- Practical Examples of find command with regex
- Search Files based on Initial Characters in the Current Directory
- Search Files in Sub Directory
- Search Files through regex patterns in every Subdirectory
- Search Files based on Extension
- Search Files based on Filename and Extension
- Final Words
- How to search filenames by regex with «find»
regex match either string in linux «find» command
Saying so would result in file names matching *.py and *.py.server .
expr1 -o expr2 Or; expr2 is not evaluated if expr1 is true.
EDIT: If you want to specify a regex, use the -regex option:
find . -type f -regex ".*\.\(py\|py\.server\)"
It would a good idea to tell people that they need to put -o expressions in parentheses in case other options follow: find . ‘(‘ -name this -o -name that ‘)’ -user xy -exec .
@Ingo Thanks. Using parenthesis is something that I also recommend, happened to omit in this case. More so because upon saying find . -type f -name «foo*» -o -name «bar*» would match directories starting with bar unless parens are specified!
Find can take a regular expression pattern:
$ find . -regextype posix-extended -regex '.*[.]py([.]server)?$' -print
-regex pattern
File name matches regular expression pattern. This is a match on the whole path, not a search. For example, to match a file named ./fubar3 , you can use the regular expression .*bar. or .*b.*3 , but not f.*r3 . The regular expressions understood by find are by default Emacs Regular Expressions, but this can be changed with the -regextype option.
-print True;
print the full file name on the standard output, followed by a newline. If you are piping the output of find into another program and there is the faintest possibility that the files which you are searching for might contain a newline, then you should seriously consider using the -print0 option instead of -print. See the UNUSUAL FILENAMES section for information about how unusual characters in filenames are handled.
-regextype type
Changes the regular expression syntax understood by -regex and -iregex tests which occur later on the command line. Currently-implemented types are emacs (this is the default), posix-awk, posix- basic, posix-egrep and posix-extended.
A clearer description or the options. Don’t forgot all the information can be found by reading man find or info find .
Regular Expression in Find command
I want to list out the files which starts with a number and ends with «.c» extension. The following is the find command which is used. But, it does not give the expected output. Command:
@Mohan As knittl said find doesn’t print just the filename, so something like this would work: find -type f -regex ‘^[.][/]1.*.c’
This also does not give expected output. Because «./
You could dispense with the regex here, as it seems to be complicating things, and just use a glob pattern, as in find -type f -name ‘5*.c’ .
2 Answers 2
It’s because the regex option works with the full path and you specified only the file name. From man find :
-regex pattern File name matches regular expression pattern. This is a match on the whole path, not a search. For example, to match a file named './fubar3', you can use the regular expression '.*bar.' or '.*b.*3', but not 'f.*r3'. The regular expressions understood by find are by default Emacs Regular Expressions, but this can be changed with the -regextype option.
where you explicitly look for a string where «the format of your filename follows any string that terminates with a slash»
UPDATE: I made a correction to the regex. I changed .* in the filename to [^\]+ as after «any string that terminates with a slash» we don’t want to find a slash in that part of the string because it wouldn’t be a filename but another directory!
NOTE: The matching .* can be very harmful.
Using Find Command With Regex
Enable the beast mode of the find command by using regex for your search.
The find command is a powerhouse for searching files based on a number of criteria.
You can enable the beast mode in the find command by using regular expression (regex) for searching.
But before jumping to the examples part, it is crucial to know some basic regex tokens and syntax.
Quick Introduction to Regex Tokens
Tokens are nothing but special characters to search for specified patterns.
So let’s have a look at some of the most basic and widely used tokens which I’ll be using with the find command:
Token | Description |
---|---|
Period (.) | It gets you a match for any character once (except a new line). So a.b will match strings such as acb, aeb and abb but won’t match accb or ab |
Backslash (\) | It eliminates the effect of special characters such as the (.) will indicate to period effect but when used a.b it will only search for strings as a.b |
Asterisk (*) | It is known as a repeater symbol. This means the preceding character can be found 0 or more times. So the ca*t will find get you ct, cat, caat etc. |
Square brackets ([]) | It will get a positive result of any character used in a string inside the square brackets. This means a[bc]d will match abd or acd, but not the abcd. |
Caret (^) | Generally, it is sued to specify the starting point of search but can also be used to negate the content when used inside the square brackets [ ^ ]. Means a[^bc]d will get you aed, azd but not abd or acd. |
Now, Let’s have a look at the basic syntax of using find with regex:
find [path] -regex [regular_expression]
- [path] is where you want to search files.
- regular_expression is where you will be using tokens to express the file pattern you are looking for.
Now it’s time for me to share some examples of how you can use find with regex.
Practical Examples of find command with regex
I am going to start with the most common scenario where a user only knows the first few characters of a file and wants to know where it is.
Search Files based on Initial Characters in the Current Directory
Currently, my file system looks like this:
And I want to search for files that start with Fo or Fr so my command will be:
Here, the -type f was used to search for files, .\/ was used to look for files in the current directory and F[or] will show us file names starting from Fo and Fr.
But what if you want to execute some commands/programs over the given result? This can be done using the find command with exec:
Search Files in Sub Directory
The above example only applied to the current directory and did not show some files that followed the same naming pattern.
So I’ll be using the same naming pattern F[or] to find files in the subdirectory:
Seems too complex right? Let me break it down for you.
Here the [^/]*\/ referees to the files that do not contain any back slashes which eliminates the possibility of finding files in the current directory.
And in the end, I’ve replaced period ( . ) with [^/] to not expand search than the first subdirectory by mentioning there should be no slashes after the filename.
Search Files through regex patterns in every Subdirectory
Seems quite complex after going searching in a single subdirectory right? Well, this is going to be the easiest one!
Well, two asterisks and that is it! Let me show you how:
And if you are curious about how it worked, it’s because I used asterisks at the beginning and the end, so it went through every possibility.
Search Files based on Extension
First, let me share the general syntax of how you are supposed to search files based on their extensions:
find ./ -type f -regex ".*\[fileextension]"
So let’s suppose I want to find all the text files (having a .txt extension) and that can be done quite easily by the given command:
Search Files based on Filename and Extension
This is my personal favorite implementation of regex with find as you can search files based on first letters and their extensions making it quite convenient.
First, let’s have a look at the syntax:
find ./ -type f -regex '\.\/[Filename].*\.[extension]'
Let’s make it a bit practical. So I’m in a scenario where I only know the first few letters of the file (started with Fo or Fr) and its extension (.sh):
Final Words
From finding files modified in n minutes to executing scripts over results with exec, find is one of the most extensive commands offering over 50+ options.
This guide explained yet another way to use the find command making you one step advanced in your Linux journey.
While this guide was kept simple, if you still have any doubts, let me know in the comments.
How to search filenames by regex with «find»
If you happen to run on OS X, then use -E . find -E . -regex ‘theregex’ to take advantage of extended (modern) regular expressions.
@SiegeX my previous comment was in case anyone might find it useful to know that in order to use optional groups you need to enable posix-extended and to give an example of what that looks like. Thank you for your answer.
Use -regex not -name, and be aware that the regex matches against what find would print, e.g. «/home/test/test.log» not «test.log»
find . -name '*.log.*.zip' -a -mtime +1
You may not need a regex, try:
find . -name '*.log.*-*-*.zip' -a -mtime +1
You will want the +1 in order to match 1, 2, 3 .
-regex pattern File name matches regular expression pattern. This is a match on the whole path, not a search. For example, to match a file named './fubar3', you can use the regular expression '.*bar.' or '.*b.*3', but not 'b.*r3'.
Also, I don’t believe find supports regex extensions such as \d . You need to use 4 .
find . -regex '.*test\.log\.9439-53-57\.zip'
Just little elaboration of regex for search a directory and file
Find a directroy with name like book
Find a file with name like book word
You do not use regex with find . -name «*book*» -type f . Using «f» for filename is still useful as an answer since only filenames shall be searched for, but you should make clear that these are globular expressions as the other answer makes clear, not regex.