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