i am trying to find directory or file that ends in any 3 characters with using
ls -l /etc | grep ???$
and this doesnt work,,
what should I type to find any directory of files that ends with 3 or 4 or 5 or 6 or 7 ... characters?
i am trying to find directory or file that ends in any 3 characters with using
ls -l /etc | grep ???$
and this doesnt work,,
what should I type to find any directory of files that ends with 3 or 4 or 5 or 6 or 7 ... characters?
find /etc -maxdepth 1 -regextype egrep -regex '.*/.{3}$'
This will find file or directory names in /etc/
that are exactly 3 characters long.
find /etc -maxdepth 1 -regextype egrep -regex '.*/.{3,}$'
And this will find files or directories in /etc/
that are a minimum of 3 characters long.
find /etc -maxdepth 1 -regextype egrep -regex '.*/.{3,7}$'
And this will find files or directories in /etc
that are anywhere from 3 to 7 characters long.
The -maxdepth 1
prevents find from searching sub-directories of /etc.
If you want to restrict the match to directories only, add -type d
after the -maxdepth 1
. For regular files, use -type f
.
If you intend to do anything with the files/dirs found, you can use find's -exec
option. e.g.
find /etc -maxdepth 1 -regextype egrep -regex '.*/.{3,7}$' -exec du -sch {} +
or xargs
(but use NUL separators to avoid problems with spaces, newlines, etc in filenames). This allows you to use any tool that can process NUL-separated input in the pipeline before xargs
. e.g.:
find /etc -maxdepth 1 -regextype egrep -regex '.*/.{3,7}$' -print0 |
head -z -n 10 |
xargs -0r ls -ld
To list the names in a single directory (i.e. not recursively) that contain at least three characters, you may use any of the globbing patterns *???
, ???*
or *???*
. Each ?
matches a single character, while *
matches any number of characters.
To list such names under /etc
with ls
:
ls -ld /etc/*???
or simply,
printf '%s\n' /etc/*???
If you want to list the names that end in three specific characters (e.g. xyz
), then use *xyz
as the pattern.
To search for such names recursively, you may (in bash
) use shopt -s globstar
to enable the **
globbing pattern (matches recursively down into subdirectories) and then...
ls -ld /etc/**/*???
The **
pattern is enabled by default in the zsh
shell.
To do something with these names (other than just calling ls
), use a loop:
shopt -s globstar
for pathname in /etc/**/*???; do
# use "$pathname" to do something
done
In the dash
shell or plain sh
, the equivalent of this loop would be
find /etc -name '*???' -exec sh -c '
for pathname do
# use "$pathname" to do something
done' sh {} +
Related:
Your use of grep
shows that you are confusing regular expressions with filename globbing patterns. In a regular expression, a dot (.
) matches any one single character, while ?
matches just the character ?
(at least in basic regular expressions, which is what grep
uses by default).
Filename patterns are also always anchored, so there's no need to explicitly anchor the pattern with $
as in a regular expression (the pattern must match the complete filename though, so xyz
matches exactly that name while *xyz
matches any filename ending in xyz
).
Related:
?
also matches on every byte that doesn't form part of valid characters.
– Stéphane Chazelas
Oct 01 '19 at 20:00