来自管道的 Bash 输入

发布于 2024-11-02 07:50:57 字数 1558 浏览 3 评论 0原文

我编写了一个简单的 bash 脚本,它从文件或 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

但是,如果没有传递任何选项,我希望它也能处理 STDIN(但如果管道中没有 STDIN,则在帮助下仍然会失败)。

也就是说,我想说:

echo "foo\nbar\nbaz" | randline

……而不是……

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

这怎么办?

编辑:
感谢杜恩!

#!/bin/bash
if [ "$( tty )" == 'not a tty' ]
then
    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

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' ]
then
    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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

马蹄踏│碎落叶 2024-11-09 07:50:57

要从文件中获取随机行,您可以执行以下操作:

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

这里我们这样做:

  1. 在每行的开头添加随机数
  2. 排序输出
  3. 从每行的开头删除随机数
  4. 打印第一行(混合输出)

顺便说一句,如果您使用的是BASH,您可以使用 $RANDOM (由 bash 提供)变量而不是自己生成 $RAND。

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.

傲世九天 2024-11-09 07:50:57

请参阅此处ksh:如何探测stdin?它适用于ksh,但答案是提供了 bash

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文