Reputation: 410
How to use find
or any other command to find files on Solaris using regular expressions.
I have managed to do it in Mac OSX and Ubuntu, but it seems that Solaris doesn't support -regex
flag.
Example in Mac OSX:
find / -type f \( -perm +111 -regex ".*[0-9]$" -o -regex ".*[mh]$" \) -exec ls -lT {} \;
Example in Ubuntu:
sudo find / -type f \( -executable -regex ".*[0-9]$" -o -regex ".*[mh]$" \) -print0 -exec ls -l --time-style=long-iso {} \;
I need to find all files that match one or multiple regular expressions at the same time in Solaris.
To be more specific, there are two files that are copied to Solaris machine: 1. script.sh 2. patterns
The script reads the patterns file line by line and create a one line find command out of all the regex patterns in the patterns file and execute is at once to list all the files that match the regex patterns.
Pattern file example:
\/usr[a-zA-Z0-9_.\/]+msg_\d+.txt
\/home[\S]+\.txt
.*[0-9]
script intended for above example:
find / -type f \( -perm +111 -regex "\/usr[a-zA-Z0-9_.\/]+msg_\d+.txt" -o -regex "\/home[\S]+\.txt" -o -regex ".*[0-9]" \) -exec ls -lT {} \;
Thanks in advance :)
Upvotes: 2
Views: 1833
Reputation: 107759
If the code you show in your first example is your real code, you don't need full regular expressions, the wildcard patterns supported by standard find
are enough.
find / -type f \( -perm +111 -name "*[0-9]" -o -name "*[mh]" \) -exec ls -lT {} \;
Note that this command looks for executable files whose name ends with a digit, and for files with any permission whose name ends with m
or h
. If you meant the permissions to apply regardless of the name, the -perm
condition would have to be outside of the parentheses.
You can install GNU find on Solaris. It may even be available as gfind
already. It's in the findutils
package.
If you need to stick to the minimal installation and you need full regexps and not just wildcard patterns, you can run ksh to do some additional filtering. Use wildcard patterns that match all the file names you want and more, and then use ksh93 and the =~
conditional operator to refine the matching.
find … -exec ksh -c 'for x do [[ $x =~ REGEX ]] || continue; ls -lT "$0"; done' _ {} +
Note that these use the extended regular expression syntax (ERE), not the basic regular expression syntax (BRE) which find -regex
uses. You can make GNU find use ERE by passing -regextype posix-extended
before -regex
.
Alternatively, if you aren't using the full power of find
(which is rarely needed), use ksh's recursive globbing to match the files, and conditionals to filter permissions and file types. Ksh's globs (@(…|…)
, *(…)
, etc.) have equivalent power to regular expressions, even though the syntax is different.
set -o globstar
for x in **/*; do
[[ -f $x && -x $x ]] || continue
ls -lT -- "$x"
done
Upvotes: 3
Reputation: 2116
If it can be assumed that no file name contains a newline then the output
of find
can be filtered through another utility, sed
in this case.
find / -type f -perm +111 | sed '/^.*[0-9]$/n;/^.*[mh]$/n;d' |
sed 's/./\\&/' | xargs ls -lT
The first use of sed
prints a line if either regular-expression matches, and the second escapes characters for xargs
ensuring that the line in
interpreted literally up to the newline.
The uses of sed
could be combined into a multi-line script:
/^.*[0-9]$/bp
/^.*[mh]$/bp
d
:p
s/./\\&/
Upvotes: 2