Ignore case when trying to match file names using find command in Linux
Or you could use find / | grep -i string
Ignore case when matching file name extensions with find
GNU
versions of find
have an -iname
flag which enables case insensitive matching of file name globs,
find ./ -iname '*.jpg'
or if you are on a system without GNU
utilities, use the bracket expressions to the glob
find ./ -name '*.[Jj][Pp][Gg]'
If you are interested in multiple name filters, just use the -o
expression for including multiple name globs
find ./ \( -iname "*.jpg" -o -iname "*.jpeg" \)
how to find file name ignoring case sensitivity in unix
Parsing the output of ls
is considered bad practice. You can use find
:
find . -iname 'ABC*' | wc -l
man find
:
-iname pattern
Like -name, but the match is case insensitive. For example, the
patterns `fo*' and `F??' match the file names `Foo', `FOO',
`foo', `fOo', etc. In these patterns, unlike filename expan‐
sion by the shell, an initial '.' can be matched by `*'. That
is, find -name *bar will match the file `.foobar'. Please note
that you should quote patterns as a matter of course, otherwise
the shell will expand any wildcard characters in them.
As Johnsyweb notes in the comment, find
will recurse into subdirectories by default. To avoid that, you can supply -maxdepth 1
:
-maxdepth levels
Descend at most levels (a non-negative integer) levels of direc‐
tories below the command line arguments. -maxdepth 0
means only apply the tests and actions to the command line
arguments.
How to ignore a file using find command
The find
command can be used with regular expressions which makes it easy to get any kind of complex search results. How it works:
- You have to use your
find
command with-regex
instead of-name
. - You have to generate a matching regular expression
How find
passes the filename to the regular expression?
Assume we have the following directory structure:
/home/someone/build/libs/abc.jar
/home/someone/build/libs/abc-plain.jar
and we are sitting in someone
if we execute find .
without any further arguments, we get:
./build/libs/abc.jar
./build/libs/abc-plain.jar
So we can for example search with regex for:
- something starts with a single dot
.
- may have some additional path inside the file name
- should NOT contain the
-
character in any number of character - ends with
.jar
This results in:
- '.'
- '/*'
- '[^-]+'
- '.jar'
And all together:
find . -regex '.*/[^-]+.jar'
or if you ONLY want to search in build/libs/
find ./build/libs -regex '.*/[^-]+.jar'
You find a online regex tool there.
Find all files with name containing string
Use find
:
find . -maxdepth 1 -name "*string*" -print
It will find all files in the current directory (delete maxdepth 1
if you want it recursive) containing "string" and will print it on the screen.
If you want to avoid file containing ':', you can type:
find . -maxdepth 1 -name "*string*" ! -name "*:*" -print
If you want to use grep
(but I think it's not necessary as far as you don't want to check file content) you can use:
ls | grep touch
But, I repeat, find
is a better and cleaner solution for your task.
How to grep for case insensitive string in a file?
You can use the -i
flag which makes your pattern case insensitive:
grep -iF "success..." file1
Also, there is no need for cat
. grep
takes a file with the syntax grep <pattern> <file>
. I also used the -F
flag to search for a fixed string to avoid escaping the ellipsis.
Trying to use GNU find to search recursively for filenames only (not directories) containing a string in any portion of the file name
specification:
- match "rain"
- in filename
- only at start of a word
- case-insensitive
assumptions:
- define "word" to be sequence of letters (no punctuation, digits, etc)
- paths have form
prefix/name
whereprefix
can have one or more levels delimited by/
and name does not contain/
constraints:
find -iregex
matches against entire path (-name
only matches filename)find -iregex
must match entirety of path (eg. "c" is only a partial match and does not match path "a/b/c")
method:
find
can return matches against non-files (eg. directories). Given definition 6, we would be unable to tell if name
is a directory or an ordinary file. To satisfy 2, we can exclude non-files using find
's -type f
predicate.
We can compare paths found by find
against our specification by using find
's case-insensitive regex matching predicate (-iregex
). The "grep" flavour (-regextype grep
) is sufficiently expressive.
Just using 1, a suitable regex is: rain
2+6+7 says we must forbid /
after "rain": rain[^/]*$
[/]
matches character in set (ie./
)[^/]
:^
inverts match: ie. character that is not/
*
matches preceding match zero or more times$
constrains preceding match to occur at end of input
3+5 says there must be no immediately preceding word characters: [^a-z]rain[^/]*$
a-z
is a shortcut for the rangea
toz
8 requires matching the prefix explicitly: ^.*[^a-z]rain[^/]*$
^
outside of[...]
constrains subsequent match to occur at beginning of input.
matches anything[^a-z]
matches a non-alphabetic
Final command-line:
find . -type f -regextype grep -iregex '^.*[^a-z]rain[^/]*$'
Note: The leading ^
and trailing $
are not actually required, given 8, and could be elided.
exercise for the reader:
- extend "word" to non-ASCII characters (eg. UTF-8)
find filenames NOT ending in specific extensions on Unix?
Or without (
and the need to escape it:
find . -not -name "*.exe" -not -name "*.dll"
and to also exclude the listing of directories
find . -not -name "*.exe" -not -name "*.dll" -not -type d
or in positive logic ;-)
find . -not -name "*.exe" -not -name "*.dll" -type f
Unix case insensitive command line search containing wldcards and spaces
For case insensitive wildcard searches when -maxdepth and -iname flags are not available for AIX Find , you can pass the Find results to Grep:
find /test/rick/. \( ! -name . -prune \) -type f -print | grep -i ".*foster.*\.txt"
find [InThisFolder] [ExcludeSubfolders] [FileTypes] | grep [InsensitiveWildcardName]
Though, this can still be problematic if you have a folder structure like "/test/rick/rick/".
The following code gives results with the current directory signifier ".":
find /test/rick/. \( ! -name . -prune \) -type f -print | grep -i ".*foster.*\.txt"
But you can pass the results to sed and find "/./" and replace with "/".
find /test/rick/. \( ! -name . -prune \) -type f -print | grep -i ".*foster.*\.txt" | sed 's/\/\.\//\//g'
* UPDATE *
Based on this page: http://mywiki.wooledge.org/ParsingLs
I’ve come up with the following command (for loop on file expansion or globbing) which avoids the problematic "/test/rick/rick/" folder structure from the find | grep solution above. It searches a folder from any folder, handles spaces, and handles case insensitivity without having to specify escape characters or upper/lower matching ([Aa]).
Just modify the searchfolder and searchpattern:
searchfolder="/test/rick"; searchpattern="*foster*.txt"; for file in "$searchfolder"/*.*; do [[ -e "$file" ]] || continue; if [[ "$(basename "$file" | tr '[:upper:]' '[:lower:]')" = $searchpattern ]]; then echo "$file"; fi; done
It does this:
- Set the folder path to search (
searchfolder="/test/rick";
) - Set the search pattern (
searchpattern="*foster*.txt"
) - Loop for every file on the search folder (
for file in "$searchfolder"/*.*;
) - Make sure the file exists (
[[ -e "$file" ]] || continue;
) - Transform any base file name uppercase characters to lowercase (
basename "$file" | tr '[:upper:]' '[:lower:]'
) - Test if the lowered base file name matches the search pattern and if so
then print the full path and filename (if [[ $(basename "$file" | tr
)
'[:upper:]' '[:lower:]') = $searchpattern ]]; then echo "$file"; fi;
Tested on AIX (Version 6.1.0.0) in ksh (Version M-11/16/88f) and ksh93 (Version M-12/28/93e).
Related Topics
Scp: How to Find Out That Copying Was Finished
How to Replace a Multi Line String in a Bunch Files
What's the Purpose of the Ud2 Opcode in the Linux Kernel
How to Remove the Last Character of the Last Line of a File
How to Find the Count of Multiple Words in a Text File
Get Last Parameter on Shell Script
How to Set Time Out from Bash Script
Is Assembler Portable Between Linux Distros
Calculate Mean of Each Column Ignoring Missing Data with Awk
Light-Weight SQL Server for Linux/Windows
What Happened to Socket If Network Has Broken Down
Add Suffix to Each Line with Shell Script
Npm Install Causes Errors Like Npm Err! Tar.Unpack Untar Error on Debian
How to Run Command During Docker Build Which Requires a Tty
How to Initialize the Attribute Group Correctly for a Platform Driver