pick script in The UNIX Programming Environment (The UNIX Programming Environment )

pick script in The UNIX Programming Environment (The UNIX Programming Environment )

Post by Tar » Mon, 11 Aug 2003 18:10:51



Hi.

In K&P 159p, there is program called pick.
as a exercise Kernighan and Pike said
"write new pick program reading in stdin but argumentes"

that is very difficult for me to write.
what make this exercise complicated is that there is no way to treat
input from stdin like input from arguments.

did anyone solve it?

 
 
 

pick script in The UNIX Programming Environment (The UNIX Programming Environment )

Post by Mark Blai » Tue, 12 Aug 2003 05:43:19



Quote:>In K&P 159p, there is program called pick.
>as a exercise Kernighan and Pike said
>"write new pick program reading in stdin but argumentes"

>that is very difficult for me to write.
>what make this exercise complicated is that there is no way to treat
>input from stdin like input from arguments.

>did anyone solve it?

This thread discusses parsing arguments from stdin:
<http://groups.google.com/groups?selm=8h2unh%24qk3%241%40duke.telepac.pt>

 
 
 

pick script in The UNIX Programming Environment (The UNIX Programming Environment )

Post by David Thompso » Tue, 12 Aug 2003 09:22:44



Quote:> In K&P 159p, there is program called pick.
> as a exercise Kernighan and Pike said
> "write new pick program reading in stdin but argumentes"

> that is very difficult for me to write.
> what make this exercise complicated is that there is no way to treat
> input from stdin like input from arguments.

> did anyone solve it?

Here's my current incarnation using ksh93.  Enjoy!

--
David Thompson
Foster City, CA

#!/usr/local/bin/ksh
#--------------------------------------------------------------------

#--------------------------------------------------------------------
# $Id: pick,v 1.10 2003/06/01 19:20:20 davidt Exp $

## -- CREDITS
## -- Brian W. Kernighan & Rob Pike, "The Unix Programming Environment"
## -- David Thompson, Jan 1991

# pick loops through each argument on its command line
# and prompts for confirmation.  If the command line is
# empty, pick uses stdin, if redirected.

## -- common variables
SCRIPT="${0##*/}"
FASTUSAGE="$SCRIPT [item...]"
USAGE="Name
    $SCRIPT - interactive pick list
Usage
    $FASTUSAGE
Where
    item         Each argument is item to accept or reject
                 Answer 'y' to print the item to stdout
                 Answer 'n' (or press return) to skip the item
                 Answer 'a' to auto accept all remaining items
                 Answer 'q' to skip all remaining items
Options
    -version     Print version control information
    -h/elp       Print this help message
Examples
    $SCRIPT one two three
    rm \`$SCRIPT *\`
    awk -F: '{print \$1}' /etc/passwd | $SCRIPT > /tmp/ids
"

## -- timestamp when this file last updated
LAST_REVISION='$Id: pick,v 1.10 2003/06/01 19:20:20 davidt Exp $'

#--------------------------------------------------------------------
# cleanup: delete temporary files upon exit
#--------------------------------------------------------------------
: ${TMPDIR:=/tmp}
trap 'cleanup 4' 1 2 3 15
function cleanup
{
    rm -f $TMPDIR/$SCRIPT.$$.*
    exit $1

Quote:}

#--------------------------------------------------------------------
# fastusage: print usage error message and exit
#--------------------------------------------------------------------
function fastusage
{
    print -u2 "$SCRIPT: Error: $*"
    print -u2 "$SCRIPT: Usage: $FASTUSAGE"
    print -u2 "$SCRIPT: Try '$SCRIPT -help' for a complete list of options"
    exit 1

Quote:}

#--------------------------------------------------------------------
# Process command line arguments
#--------------------------------------------------------------------

## -- loop to process arguments
while [[ $# -ne 0 ]] ; do
    case "$1" in
        -h|-help) print "$USAGE" ; exit 0 ;;
        -version) print "$LAST_REVISION" ; exit 0 ;;
        --) shift ; break ;;
        -*) fastusage "Unknown option: $1" ;;
        *)  break ;;
    esac
    shift
done

## -- nothing to do?
if [[ $# -eq 0 && -t 0 ]] ; then
    print "$USAGE"
    exit 0
fi

#--------------------------------------------------------------------
# MAIN LOGIC
#--------------------------------------------------------------------

## -- Here we collect our arguments from stdin if none are supplied
## -- on the command line; cat will read stdin until EOF and save to
## -- our temporary file, then we reset the IFS to a newline in order
## -- to preserve spaces in each line of input, then we prep the main
## -- loop by resetting the positional parameters and restoring IFS.
if [[ $# -eq 0 ]] ; then
    TMPFILE=$TMPDIR/pick.$$.tmp
    cat > $TMPFILE
    OLDIFS="$IFS"
    IFS='
'
    set -- $(<$TMPFILE)
    IFS="$OLDIFS"
fi

## -- Using fd 3 & 4 isn't strictly necessary, but this technique
## -- illustrates how we can read & write to the terminal without
## -- actually changing stdin & stdout and without using a subshell.
exec 2> /dev/tty    # redirect all stderr to tty
exec 3< /dev/tty    # use this for terminal input
exec 4> /dev/tty    # use this for terminal output

ANSWER=

    if [[ "$ANSWER" != "a" ]] ; then
        print -n -u4 "$arg? "
        read ANSWER
    fi
    case "$ANSWER" in
       y) print "$arg" ;; # yes
       a) print "$arg" ;; # all  (auto accept remaining args)
       q) break ;;        # quit (auto reject remaining args)
    esac
done <&3

cleanup 0

 
 
 

pick script in The UNIX Programming Environment (The UNIX Programming Environment )

Post by Tar » Fri, 15 Aug 2003 16:51:59



> Here's my current incarnation using ksh93.  Enjoy!

> ...

your pick is great!
but can't treat arguments well like kernighan's pick do.
for example, see following
--
$ pick                     # if no argument, stdin input mode
-> "a b" c d               # get input from stdin
a b?                       # your pick echo only "a", not with b
n
c?
n
d
?
--