Ignore Case When Trying to Match File Names Using Find Command in Linux

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:

  1. You have to use your find command with -regex instead of -name.
  2. 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:

  1. something starts with a single dot .
  2. may have some additional path inside the file name
  3. should NOT contain the - character in any number of character
  4. ends with .jar

This results in:

  1. '.'
  2. '/*'
  3. '[^-]+'
  4. '.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:

  1. match "rain"
  2. in filename
  3. only at start of a word
  4. case-insensitive

assumptions:


  1. define "word" to be sequence of letters (no punctuation, digits, etc)
  2. paths have form prefix/name where prefix can have one or more levels delimited by / and name does not contain /

constraints:


  1. find -iregex matches against entire path (-name only matches filename)
  2. 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 range a to z

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:


  1. 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



Leave a reply



Submit