1

I want to select all the files in the current folder that start with either one or two numerical character. e.g.:

1- filenameA
2- filenameB
....
17- filenameT
18- filenameU

I would like to know how I select only the files that start with up to 2 numerical characters.

So far I have tried

$ find . -name '[0-9]{1,2}*' 

But it doesn't return anything, which I don't understand why. My reasoning when writing this command was:

[0-9]     select any string starting with a number from 0 to 9
{1,2}     and this can be repeated 1x or 2x

What am I getting wrong?

my INelegant solution so far

run the below two commands to tackle first the [0-9] range and then [10-99] range

$ find . -name '[0-9]-*'
$ find . -name '[0-9][0-9]-*'
oguz ismail
  • 1
  • 16
  • 47
  • 69
asa
  • 675
  • 2
  • 7
  • 17
  • 1
    sorry, it was missing the dash "-" in my solution. So it's not matching everything. I corrected it now – asa May 24 '21 at 18:14
  • `-name` takes a pattern, not a regular expression. See if your version of `find` supports something like `-regex`, like GNU `find` does. – chepner May 24 '21 at 18:15
  • no, it doesn't answer. This answer is too general (filenames starting with a number). My problem is: files starting specifically with one or max two numerical chars. – asa May 24 '21 at 22:37
  • and on top of that, the answers provided here have much more information (better explained) than the answers in the other post, which help me understand more the content. So happy to having asked this question. – asa May 25 '21 at 09:17

3 Answers3

2

You don't need find for that.

$ touch 7-foo 42-bar 69-baz
$ printf '%s\n' [0-9]{,[0-9]}-*
7-foo
42-bar
69-baz
$ shopt -s nullglob
$ printf '%s\n' {0..99}-*
7-foo
42-bar
69-baz
oguz ismail
  • 1
  • 16
  • 47
  • 69
  • i don't want to print the files but rather select them with find, so it's easier to pipe the output with another command. If I'm not mistaken the only way to pipe the "printf" would be by writing the output to a temporary file and then reading this temporary file with another command, right? – asa May 24 '21 at 22:35
  • `printf` is for demonstration here. You can use those globs with any command. – oguz ismail May 25 '21 at 05:59
1

You can use gnu find like this with -regex option:

find . -maxdepth 1 -type f -regex '.*/[0-9][0-9]?-.*'

Details:

  • -maxdepth 1: In current directory only
  • -type f: Match files only
  • -regex '.*/[0-9][0-9]?-.*': Match 1 or 2 digits in filename at the start before matching a -

If you don't have gnu find then you may use:

find . -maxdepth 1 -type f \( -name '[0-9][0-9]-*' -o -name '[0-9]-*' \)
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • for it works even without the regex mode. do you know why? – asa May 24 '21 at 18:20
  • Yes we can remove `-regextype awk` as we are not using any extended regex here. I have made correction in answer to add a hyphen. – anubhava May 24 '21 at 18:26
1

In your initial code, you are trying to use a regular expression where find's -name is expecting you to use shell pattern matching notation.

Your original "INelegant solution" using -name '[0-9]*' will fail because [0-9]* matches all files starting with a digit not just those with only one digit. Your updated solution should work better and can be written as a single command:

find \( -name '[0-9]-*' -o -name '[0-9][0-9]-*' \) ...

Alternatively, with POSIX find, you could search for filenames that start with a digit but exclude any whose third character is a digit:

find . -type f -name '[0-9]*' ! -name '??[0-9]*'

To not descend into sub-directories is slightly complicated if your find does not have -maxdepth option:

find . ! -name . -prune -type f -name '[0-9]*' ! -name '??[0-9]*'

! -name . matches everything except the starting directory. Applying -prune to them avoids the sub-directory descent.

jhnc
  • 11,310
  • 1
  • 9
  • 26
  • Sorry, I forgot to add the dash '-' in my solution. I corrected it now. – asa May 24 '21 at 18:15
  • in my understanding "glob = wildcards". what you mean by glob here is: POSIX basic? am I right? if so, I agree with you, I believe "find" is expecting POSIX basic whilst I'm passing POSIX extended – asa May 24 '21 at 19:11
  • thanks, I've made my answer more precise – jhnc May 24 '21 at 21:18