简体   繁体   中英

How to find files in Solaris using multiple regular expressions

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 :)

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

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/./\\&/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM