您的位置 首页 > 腾讯云社区

啥?还不知道shuf,那你一定写了很多废代码!Bash程序员,说你呢---程序员小助手

引言

作为大多数熟练的 bash 程序员,都有可能没有听说过 shuf 这个指令。

不管你用或者不用,它都静静的躺在那里,从Linux发行版开始,它已经内置在指令集里了。

敢于冒险的人找到了 shuf,从此也改变了自己对他的看法。

shuf 是什么

在本文中我们尝试深入的了解 shuf 这个指令。

shuf是一个类似sort的命令行实用程序,包含在Coreutils中。您可能已经猜到,它用于伪随机给定的输入,就像您洗牌一样。你猜对了!

字如其人,它的名称也跟它的功能一样一目了然。

找到了这个指令,那就用起来吧,像其他大多数指令一样,在终端命令行里用 --help 打印出它的可选项。

shuf在哪些领域比较有用呢?有三个方面。

文件 file。列表 list。区间 range。

每种方式都有其优点,提前预习下 shuf 指令的用法,可以尽量避免使用中出现的错误。

操作文件

文件操作是下坡最常用的方式。选项中包含 -e 或者 -i,默认为文件操作。也就是说,命令行告诉该指令要输入的是一个文件。

文件来源可以是标准输入,或者是手动指定的文件路径。

参数列表的最后一个参数,也就可能是路径名或文件名。如果省略参数,则视为从标准输入读取。

下面是一些示例,明确指定文件来源。

标准输入隐式作为文件

这样,我们就从shuf命令的参数中省略了file。根据约定,您可以选择 - 来代替文件,以指示将该文件作为标准输入。

seq 3 | shuf

输出内容为,

1 3 2

标准输入显式作为文件

在命令行执行以下指令,

seq 3 | shuf -

输出内容如下,

3 1 2

我们可以看到上述两种方式。所达到的效果是一样的。

明确指定文件名

通过这种方式,我们在shuf命令的参数中指定一个文件名作为文件。下面是几个使用文件的文件shuf示例。

从终端输入

执行以下指令,

shuf /dev/fd/1

/dev/fd/1 其实就是类UNIX系统中的标准输入。命令行 Enter 之后。会停留在输入窗口。如上图所示,输入任意字符串。最后按 Ctrl + D 结束输入。shuf 将输入的文本随机打断并输出。

打乱文件的行

输入以下指令,

seq 3 > tmp.txt shuf tmp.txt rm -f tmp.txt

输出内容如下,

2 1 3列表

在这种方式中,我们操作一个文件或通过管道输入到shuf命令中。通过这种方式,我们允许使用 -e 选项将输入行指定为shuf命令的参数,从而强制 shuf 作为列表 shuf 进行操作。

用法如下,

Usage: shuf -e [OPTION]... [ARG]...

在终端输入一些命令,

shuf -e 1 2 3

输出内容如下,

1 3 2

上述指令作用等同于

seq 3 | shuf -

使用变量作为参数

在终端输入以下指令,

var="1 2 3"; shuf -e ${var}

这个没有这个例子很简单,就是使用了 bash 变量进行操作。变量中存储了一个列表。

当然了,生成列表也可以用 bash 内置的方式。

shuf -e {1..3}

输出内容如下,

1 2 3

bash 的一些其他玩法,

shuf -e $( seq 3 )

本质上与命令符、管道、重定向,或文件内容读取原理是一致的。

区间

最后一种方法与前面介绍的方法不同。它不需要在命令行中指定文件或参数,而是需要一个整数范围。-i 选项强制 shuf 作为 range shuf 操作。

区间 shuf 生成一个按随机顺序排列的整数范围。

用法如下,

Usage: shuf -i LO-HI [OPTION]...

先举一个例子,

shuf -i 1-3

输出内容如下,

2 3 1一些高级选项

下面列出的这些高级选项,在 bash 脚本编程中可能会很有用。

限制输出行数

运行以下指令,

shuf -i 1-3 -n 1

输出内容如下,

3

我们使用参数 -n 指定输出的行数。本例中 -n 等于 1,那么仅输出一行。

指定输出文件

像其他一些Linux中的指令一样,-o 用于指定输出文件名。举例说明,

shuf -i 1-3 -n 1 -o filter.txt cat filter.txt rm -f filter.txt

输出内容如下,

1

流操作

为了创建连续的输出行流,我们使用-r选项,如下所示。

shuf -e {0,1} -r | xargs -i echo -n "{}"

输出内容如下,

000101101010101101010110000101111010001010111001110…

使用代替n用作分隔符

使用作为分隔行,仅需要使用 -z 选项。举例如下:

seq 3 | tr 'n' '' | shuf -z

输出内容如下:

213如果没有shuffle,bash随机函数长什么样?

下面使用 gawk 实现类似 shuf 的功能,我们看看区别在哪里。

闲言少叙,直接上脚本。

gawk-shuf() { gawk -v random=${RANDOM} ' function randInt() { return int(rand()*1000) } function case_numeric_compare(i1, v1, i2, v2, l, r) { l = int(v1) r = int(v2) if(l<r) return -1 else if(l==r) return 0 else return 1 } BEGIN { count=1 srand(random) } { rank[count]=randInt() line[count]=$(0) count++ } END { asorti(rank,order,"case_numeric_compare") for(i=0;i&lt;count;i++) { print line[order[i]] } } ' - }if [ ${#} -eq 0 ]then trueelse exit 1 # wrong argsfi gawk-shuf

功能是一样的,但是效率很低,维护起来很麻烦,对不对?

写在最后

大神们都已经准备好工具了,我们只用把它拿出来使用,不要重复造轮子了。

---来自腾讯云社区的---程序员小助手

关于作者: 瞎采新闻

这里可以显示个人介绍!这里可以显示个人介绍!

热门文章

留言与评论(共有 0 条评论)
   
验证码: