SonicProtein
SonicProtein

Reputation: 850

How to find files with specific pattern in directory with specific number? Linux

I've got folders named folder1 all the way up to folder150 and maybe beyond.. but I only want to find the complete path to text files in some of the folders (for example folder1 to folder50).

I thought a command like the following might work, but it is incorrect.

find '/path/to/directory/folder{1..50}' -name '*.txt'

The solution doesn't have to use find, as long as it does the correct thing.

Upvotes: 1

Views: 1781

Answers (3)

mklement0
mklement0

Reputation: 437548

V. Michel's answer directly solves your problem; to complement it with an explanation:

Bash's brace expansion is only applied to unquoted strings; your solution attempt uses a single-quoted string, whose contents are by definition interpreted as literals.

Contrast the following two statements:

# WRONG:
# {...} inside a single-quoted (or double-quoted) string: interpreted as *literal*.
echo 'folder{1..3}' # -> 'folder{1..3}'

# OK:
# Unquoted use of {...} -> *brace expansion* is applied.
echo 'folder'{1..3} # -> 'folder1 folder2 folder 3'

Note how only the brace expression is left unquoted in the 2nd example above, which demonstrates that you can selectively mix quoted and unquoted substrings in Bash.


It is worth noting that it is - and can only be - Bash that performs brace expansion here, and find only sees the resulting, literal paths.[1]

find only accepts literal paths as filename operands.
(Some of find's primaries (tests), such as -name and -path, do support globs (as demonstrated in the question), but not brace expansion; to ensure that such globs are passed through intact to find, without premature expansion by Bash, they must be quoted; e.g., -name '*.txt')


[1] After Bash performs brace expansion, globbing (pathname expansion) may occur in addition, as demonstrated in ehaymore's answer; folder(?,[1-4]?,50) is brace-expanded to tokens folder?, folder[1-4]?, and folder50, the first two of which are subject to globbing, due to containing pattern metacharacters (?, [...]). Whether globbing is involved or not, the target program ultimately only sees the resulting literal paths.

Upvotes: 2

V. Michel
V. Michel

Reputation: 1619

find /path/to/directory/folder{1..50} -name '*.txt'  2>/dev/null 

Or only basename

find /path/to/directory/folder{1..50} -name '*.txt' -exec basename {} \; 2>/dev/null

Or basename without .txt

 find /path/to/directory/folder{1..50} -name '*.txt' -exec basename {} .txt \; 2>/dev/null

Upvotes: 2

ehaymore
ehaymore

Reputation: 217

You can give multiple directories to the find command, each matching part of the pattern you're looking for. For example,

find /path/to/directory/folder{?,[1-4]?,50} -name '*.txt'

which expands to three patterns:

  • folder? (matches 0-9)
  • folder[1-4]? (matches 10-49)
  • folder50

The question mark is a single-character wildcard.

Upvotes: 1

Related Questions