Linux find all source files

How can I recursively find all files in current and subfolders based on wildcard matching?

find needs a starting point, so the . (dot) points to the current directory.

I know this is tagged as linux but this is worth mentioning: the path is required for on other *nix variants that aren’t linux. On linux, the path is optional if you want to use dot.

@Seatter «foo*» tells find to look for all files that start with «foo». It is just his example. You could use «gpio*» to find all files who’s names start with gpio, or just «gpio1» to find all files named gpio1.

note that the «foo*» is in quotes so the shell doesn’t expand it before passing it to find. if you just did find . foo* , the foo* would be expanded AND THEN passed to find.

Also useful: If you don’t want to be notified about directories you don’t have permission to (or other errors), you can do find . -name «foo*» 2>/dev/null

Piping find into grep is often more convenient; it gives you the full power of regular expressions for arbitrary wildcard matching.

For example, to find all files with case insensitive string «foo» in the filename:

find also has the -iname , -regex , and -iregex flags for case-insensitive wildcard, regex, and case-insensitive regex matching, so piping to grep is unnecessary.

However, piping to grep -v can allow you to use simple strings or regexes to remove entries you don’t want.

@iobender — Sadly, I can tell you from experience that not all systems come with a find command that supports those options. Sometimes grep becomes the only option.

One important caveat here is that if you’re using find on a directory that contains A LOT of files (eg; «) then this can be quite slow.

find will find all files that match a pattern:

However, if you want a picture:

fd

In case find is too slow, try the fd utility — a simple and fast alternative to find written in Rust.

In a few cases, I have needed the -L parameter to handle symbolic directory links. By default symbolic links are ignored. In those cases it was quite confusing as I would change directory to a sub-directory and see the file matching the pattern but find would not return the filename. Using -L solves that issue. The symbolic link options for find are -P -L -H

L switch is very helpful. Many times user do not have any idea about underlying directories, whether they are softlinked or are normal directories. So in case of doubt, it always good to use L option. At least, it has always helped me.

In the wildcard-match you can provide the string you wish to match, e.g., *.c (for all C files).

Your answer is the first most correct here as it only searches files as specified. The others not specifying type will return directories.

By default, find detect symbolic file links (but not the ones in symbolic directory links). -type f will cause find to not detect symbolic file links. If you also want to include symlinks that point to a file, use -L : find -L -type f . Don’t use -type f,l since it will also include symbolic directory links.

Читайте также:  Sms шлюз для linux

If your shell supports a new globbing option (can be enabled by: shopt -s globstar ), you can use:

to find any files or folders recursively. This is supported by Bash 4, zsh and similar shells.

Personally I’ve got this shell function defined:

Note: Above line can be pasted directly to shell or added into your user’s ~/.bashrc file.

Then I can look for any files by typing:

Alternatively you can use a fd utility with a simple syntax, e.g. fd pattern .

@Broncha Because you need to activate the extended globbing by shopt -s globstar command. This is supported in Bash, zsh and similar shells.

find path/to/dir -name "*.ext1" -o -name "*.ext2" 

Explanation

  1. The first parameter is the directory you want to search.
  2. By default find does recursion.
  3. The -o stands for -or . So above means search for this wildcard OR this one. If you have only one pattern then no need for -o .
  4. The quotes around the wildcard pattern are required.
find . -type f -name 'text_for_search' 

If you want use a regular expression, use -iname :

find . -type f -iname 'text_for_search' 

The default way to search for files recursively, and available in most cases is

It starts recursively traversing for filename or pattern from within the current directory where you are positioned. With the find command, you can use wildcards, and various switches. To see the full list of options, type

Or if man pages aren’t available at your system:

However, there are more modern and faster tools than find, which are traversing your whole filesystem and indexing your files. One such common tool is locate or slocate/mlocate. You should check the manual of your OS on how to install it, and once it’s installed, it needs to initiate the database. If the install script doesn’t do it for you, it can be done manually by typing

And, to use it to look for some particular file, type:

Or, to look for a filename or pattern from within the current directory, you can type:

pwd | xargs -n 1 -I <> locate "filepattern" 

It will look through its database of files and quickly print out path names that match the pattern that you have typed. To see the full list of locate’s options, type: locate —help or man locate

Additionally, you can configure locate to update its database on scheduled times via a cron job, so a sample cron which updates the database at 1 AM would look like:

These cron jobs need to be configured by root, since updatedb needs root privileges to traverse the whole filesystem.

Источник

How to list all source files (*.c, *.cpp, *.h)

I’d like to find source files (*.c, *.cpp, *.h) that contain in Linux/MinGW/Cygwin, and recursively in all sub directories. My basic idea is using find and grep . However, building a regular expression that can check given file name is either *.c, *.cpp, or *.h isn’t easy. Could you help me out?

7 Answers 7

find Linux/MinGW/Cygwin -name '*.c' -o -name '*.cpp' -o -name '*.h' 

@Ali: It anchors the regex to the end of the line (it prevents finding files named foo.cpp.old for example).

Читайте также:  Astra linux модули ядра

In my macbook, the script without a -E can’t find anything. you might need add a -E (as extended) to make it more portable, just like find -E . -regex ‘.*\.(c|h|cpp)’ -print . 😉

Quick and dirty, and avoids directory names:

There are three problems with this command: 1. It won’t find *.cpp files. 2. It will find *.| files. 3. The glob will expand if there are matching files in the current directory. Quoting prevents that.

You can use a slightly simpler regex:

I use a mac pro which also works in bash. But every time I type in the command line:

it says illegal option. So I just simplified it as:

and found it really worked!

I don’t think that does what you think. I think the shell is expanding the * before being passed to find . What you end up with is something like find file1.c file1.h file2.c , etc. , and only for files in the current directory, not any sub-directories. The shell only expands * to the names of files in the current directory. You can just use ls for that.

On my mac book pro , the following did the trick:

You must log in to answer this question.

Hot Network Questions

Subscribe to RSS

To subscribe to this RSS feed, copy and paste this URL into your RSS reader.

Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.7.14.43533

By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.

Источник

Find all files with name containing string [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.

This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.

I have been searching for a command that will return files from the current directory which contain a string in the filename. I have seen locate and find commands that can find files beginning with something first_word* or ending with something *.jpg . How can I return a list of files which contain a string in the filename? For example, if 2012-06-04-touch-multiple-files-in-linux.markdown was a file in the current directory. How could I return this file and others containing the string touch ? Using a command such as find ‘/touch/’

8 Answers 8

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:

But, I repeat, find is a better and cleaner solution for your task.

@Dru, if you want it ‘shorter’ you can avoid -print as this is the default behaviour and . as this is the default folder where it checks.

Awesome. I see myself using this a lot. I will take your -print and . removal suggestions, make it a command, and try to pass *string* in as a command line argument.

Читайте также:  Посмотреть wifi сети linux

find . -name «*string*» Works great too. Removing . throws an error on my end. Thanks again @Zagorax.

Just an observation, the above command complained about the position of -maxdepth argument better to move it before -name as @Sunil Dias mentioned

I have find *.jpg -name «*from*» -print which works for a given directory. How can I make search recursively? I’ve tried -maxdepth .

-R means recurse. If you would rather not go into the subdirectories, then skip it.

-i means «ignore case». You might find this worth a try as well.

Great. I noticed that some file contents follow a : . Is there anyway to withhold that? Using an option perhaps?

That seems to only produce the contents of the files. You essentially answered my question though, I can try to do some digging for withholding the contents.

Ah. you only need the file names? Run : grep -R «touch» . | cut -d «:» -f 1 (sorry must have misread you).

Thanks @carlspring this is interesting. grep either returns files with contents and filenames containing touch or contents containing touch , I’m not sure which is the case, yet. Of the list of files returned, half contain touch in the title and the other half conatains touch in the body, not the title. Just realized this.

The -maxdepth option should be before the -name option, like below.,

find . -maxdepth 1 -name "string" -print 
find $HOME -name "hello.c" -print 

This will search the whole $HOME (i.e. /home/username/ ) system for any files named “hello.c” and display their pathnames:

/Users/user/Downloads/hello.c /Users/user/hello.c 

However, it will not match HELLO.C or HellO.C . To match is case insensitive pass the -iname option as follows:

find $HOME -iname "hello.c" -print 
/Users/user/Downloads/hello.c /Users/user/Downloads/Y/Hello.C /Users/user/Downloads/Z/HELLO.c /Users/user/hello.c 

Pass the -type f option to only search for files:

find /dir/to/search -type f -iname "fooBar.conf.sample" -print find $HOME -type f -iname "fooBar.conf.sample" -print 

The -iname works either on GNU or BSD (including OS X) version find command. If your version of find command does not supports -iname , try the following syntax using grep command:

find $HOME | grep -i "hello.c" find $HOME -name "*" -print | grep -i "hello.c" 
find $HOME -name '[hH][eE][lL][lL][oO].[cC]' -print 
/Users/user/Downloads/Z/HELLO.C /Users/user/Downloads/Z/HEllO.c /Users/user/Downloads/hello.c /Users/user/hello.c 

If the string is at the beginning of the name, you can do this

$ compgen -f .bash .bashrc .bash_profile .bash_prompt 

compgen is not an appropriate hammer for this nail. This little-used tool is designed to list available commands, and as such, it lists files in the current directory (which could be scripts) and it can neither recurse nor look past the beginning of a file name nor search file contents, making it mostly useless.

An alternative to the many solutions already provided is making use of the glob ** . When you use bash with the option globstar ( shopt -s globstar ) or you make use of zsh , you can just use the glob ** for this.

does a recursive directory search for files named bar (potentially including the file bar in the current directory). Remark that this cannot be combined with other forms of globbing within the same path segment; in that case, the * operators revert to their usual effect.

Note that there is a subtle difference between zsh and bash here. While bash will traverse soft-links to directories, zsh will not. For this you have to use the glob ***/ in zsh .

Источник

Оцените статью
Adblock
detector