Menu

Simulating the unix/linux "find" command

2016-05-02
2016-08-05
  • Lowell Boggs, Jr.

    The standard unix find command is powerful and flexible and is necessary because the unix ls command was originally designed for human readability.

    In brash, the .ls command acts like a cross between the windows "dir /b" command and "the linux ls -l" command. Because of its interface, the complexity of unix's find command is not as necessary. Basically, .ls gives most of the features of find -- though not the ability to invoke commands on each file or test specific file attributes.

    The basic logic of using find is to pipe the results to some program that uses the names, like this:

    find [options] directories   |   use_the_results
    

    In brash, the same thing would be done with .ls

    .ls -R directories | use_the_results
    

    If it is not convenient to embed the logic of filtering the list of file names in use_the_results, then an intermediate loop can be used:

    .ls -R directories | 
    while read file
    do
       if [ testOperator file ]
       then
           echo "$file"   # only print the needed file names
        fi
    done | use_the_results
    

    Note that there are several testOperator that can be used to filter names:

    TestExpr syntax:
        [ -f file ] -- check for file or directory existence
        [ -e file ] -- confirm that file exists and is not a directory
        [ -r file ] -- check for file exists and is readable
        [ -w file ] -- check for file exists and is writeable
        [ -x file ] -- check for file exists and is executable
        [ -s file ] -- check for file exists and has non-zero size
    

    Additionally case statements can be used to interpret parts of the file name

    .ls -R directories | 
    while read file
    do
        case "$file"
            *.c) echo "$file" ;;
            *.h) echo "$file" ;;
        esac
    done | use_the_results
    

    See also the .stat command in brash which lets you get at more details of the file than the test operators provide.

    Here's its -h output:

    <brash builtin> .stat:  print file attributes for use by the eval command
    
    Usage:
    
        .stat [-h]  [file ...]
    
    Description
        Print the attributes of each named file in a format that the eval
        statement can then read into environment variables.  For example
    
          eval $(.stat fred.cxx)
    
        This invocation invokes .stat on file fred.cxx, then sets environment
        variables with the file's attributes.
    
    Attribute values presented
        The following lines are produced for each file:
    
        sfName=...    The file name as entered on the command line
        sfFull=...    The full pathname of the file
        sfPath=...    The full directory name
        sfBase=...    The nodename and extension of the file
        sfNode=...    Leaving out the path and the extension
        sfExt=...     Just the extension
        sfMTime=...   The time in seconds of the last modification
        sfCTime=...   The time in seconds of the last attribute change
        sfATime=...   Supposedly the time in seconds of the last access.
        sfUID=...     The user id number
        sfGID=...     The group id number
        sfMODE=...    The octal value of the file mode
        sfMODS=...    The string value of the file mode
    
    Notes: Multiple files can be specified on the command line, but eval won't
           know how to separate them out, so in general, only one parameter
           makes sense.
    
           See the .date command for formatting seconds into human readable
           strings.
    
     
  • Lowell Boggs, Jr.

    By release 1.2.12, the .ls builtin command now has a couple of useful command line options to aid in implementing unix find-like operations:

    --sep=string (which lets you define something other than space as a field separator)
    --seconds (which causes the time to be printed in seconds since 1970)

    These options allow you to more easily parse the fields in the .ls outpout -- particularly if you combine them with the .cut command.

     

Anonymous
Anonymous

Add attachments
Cancel