开发者

Bash input from pipe

I wrote a trivial bash script which dumps a random line from a file or STDIN:

#!/bin/bash
if [ $# -ne 1 ]
then
    echo "Syntax: $0 FILE (or \'-\' for STDIN)"
    echo $0 - display a random line from FILE
    exit 1
fi

RAND=`cat /proc/sys/kernel/random/uuid | cut -c1-4 | od -d | head -1 | cut -d' ' -f2`

if [ $1 != "-" ]
then
    LINES=`cat "$1" | wc -l`
    LINE=`expr $RAND % $LINES + 1`
    head -$LINE $1 | tail -1
else
    piped=`cat -`
    LINES=`echo "$piped" | wc -l`
    LINE=`expr $RAND % $LINES + 1`
    echo "$piped" | head -$LINE | tail -1
fi

However, I'd like it to also process STDIN if there are no options passed (but still fail with the help if there's no STDIN from a pipe).

That is, I'd like to say:

echo "foo\nbar\nbaz" | randline

... instead of ...

echo "foo\n\bar\nbaz" | randline -

How can this be done?

Edit:

Thanks to Doon!

#!/bin/bash
if [ "$( tty )" == 'not a tty' ]
t开发者_如何学JAVAhen
    STDIN_DATA_PRESENT=1
else
    STDIN_DATA_PRESENT=0
fi

if [[ $# -ne 1 && $STDIN_DATA_PRESENT -eq 0 ]]
then
    echo "Syntax: $0 [FILE (or \'-\' for STDIN)]"
    echo $0 - display a random line from FILE
    echo -e "\nWill also process piped STDIN if no arguments are given."
    exit 1
fi

RAND=`cat /proc/sys/kernel/random/uuid | cut -c1-4 | od -d | head -1 | cut -d' ' -f2`

if [[ $1 && $1 != "-" ]]
then
    LINES=`cat "$1" | wc -l`
    LINE=`expr $RAND % $LINES + 1`
    head -$LINE $1 | tail -1
else
    piped=`cat -`
    LINES=`echo "$piped" | wc -l`
    LINE=`expr $RAND % $LINES + 1`
    echo "$piped" | head -$LINE | tail -1
fi


To get random line from a file you can do:

awk 'BEGIN{srand();}{printf "%04d %s\n", int(rand()*10000), $0}' < $FILENAME | sort | cut -f2- -d' ' | head -1

Here we do:

  1. add random number to the beginning of each line
  2. sort output
  3. remove random number from the beginning of each line
  4. print first line (of mixed output)

BTW, in if you are using BASH, you can use $RANDOM (provided by bash) variable instead of generating $RAND by your self.


see here ksh: how to probe stdin? it is for ksh, but an answer for bash is provided

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜