224

I have a directory with roughly 100000 files in it, and I want to perform some function on all files beginning with a specified string, which may match tens of thousands of files.

I have tried

ls mystring*

but this returns with the bash error 'Too many arguments'. My next plan was to use

find ./mystring* -type f

but this has the same issue.

The code needs to look something like

for FILE in `find ./mystring* -type f`
do
    #Some function on the file
done
SecretAgentMan
  • 2,856
  • 7
  • 21
  • 41
RikSaunderson
  • 3,505
  • 6
  • 32
  • 50

3 Answers3

392

Use find with a wildcard:

find . -name 'mystring*'
2240
  • 1,547
  • 2
  • 12
  • 30
Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
  • 13
    and to execute some function "find . -name 'mystring*' -exec [command]" for example delete "find . -name 'mystring*' -exec rm {} \;" – Eldar Oct 27 '10 at 15:31
  • 3
    Where {} is a placeholder for file name :-) (so you can construct your own actions) – Sergio Tulentsev Oct 27 '10 at 15:34
  • 1
    This seems to return all results *containing* the string? The – Brian Z Oct 17 '14 at 06:56
  • 12
    ...or `find . -iname 'mystring*'` for case insensitive search. – Frank N Mar 12 '17 at 12:52
  • 2
    OP refers to a single directory so insert `-maxdepth 1` before the `-name` to limit find to the current folder – jacanterbury Mar 14 '18 at 11:37
  • @jacanterbury: it is not clear if this directory contains other directories (besides the 100k files). It it doesn't, this is not needed. But thanks, might be useful to someone. – Sergio Tulentsev Mar 14 '18 at 11:40
  • @eldar I've used this, and realize that I admittedly still don't know what the \; does. Any easy explanation for future readers? – mochsner Apr 29 '22 at 02:49
  • @SergioTulentsev I am using If condition but not working. if [[ find /tmp/home/my_location -name 'mystring*'.ctl ]] – Bhagesh Arora May 15 '22 at 18:10
  • it would be nice if this were the default, i.e. I could just find anything in the current directory + subdirectories by typing `find my_file`, I always forget this syntax... – Jan M. May 26 '23 at 11:18
33
ls | grep "^abc"  

will give you all files beginning (which is what the OP specifically required) with the substringabc.
It operates only on the current directory whereas find operates recursively into sub folders.

To use find for only files starting with your string try

find . -name 'abc'*

jacanterbury
  • 1,435
  • 1
  • 26
  • 36
  • Don't use ls | grep. Use a glob or a for loop with a condition to allow non-alphanumeric filenames, see https://github.com/koalaman/shellcheck/wiki/SC2010 – Nicolas Massart Oct 26 '21 at 13:20
  • "Don't use" is perhaps a little directive. 'ls /directory/*mystring*' will drill down to sub-directories which you may not want to do, and using glob and loops is more complicated. Granted the ls | grep approach has weaknesses however its simplicity makes it an attractive solution for some people and in some situations. – jacanterbury Jul 20 '22 at 09:40
  • 1
    Yes, "be careful when using ls | grep" is perhaps better. But I was just quoting the shell check rule. – Nicolas Massart Jul 20 '22 at 12:10
8

If you want to restrict your search only to files you should consider to use -type f in your search

try to use also -iname for case-insensitive search

Example:

find /path -iname 'yourstring*' -type f

You could also perform some operations on results without pipe sign or xargs

Example:

Search for files and show their size in MB

find /path -iname 'yourstring*' -type f -exec du -sm {} \;
mati kepa
  • 2,543
  • 19
  • 24