Shell随机生成几个不重复的随机数

本文介绍了一个简单的Shell脚本实例,用于模拟36选7的彩票游戏。该脚本通过循环和条件判断确保能够随机选择七个1到36之间的不重复数字,并通过sort和uniq命令进行排序及去重。
模拟体育彩票,36选7。
要求:随机,7个不重复,1到36这些整数。


#!/bin/bash

touch ./temp
>temp

while [ `sort temp | uniq | wc -l` != 7 ]
do
echo `expr $RANDOM % 36 + 1` >> temp
done

sort temp | uniq

rm temp


just for fun... 练习一下shell编程。
<think>好的,用户现在想用shell命令生成动态的user_id,格式是"user_id": "U123456789",并且允许重复值。之前我给他们提供了Python的解决方案,但这次他们明确要求使用shell命令。需要参考之前的引用内容,特别是引用1提到的执行列表类型的shell命令以及可能的子进程死锁问题,但用户现在需要处理Python的子进程,而是直接用shell命令生成。 首先,用户需要生成U后面跟9位数字的字符串。允许重复意味着需要唯一性保证,所以可能用随机数或者简单的方法。在shell生成随机数可以用$RANDOM,但它的范围是0-32767,最多5位数,够9位。所以需要组合多个随机数或者使用其他方法。 参考引用4中的printf用法,可能需要用printf来格式化输出。比如用date命令获取时间戳的部分,或者结合其他命令生成数字。例如,使用date +%s获取秒数,然后截取后面的几位数字,再加上随机数补足位数。 另外,用户允许重复,所以需要像之前的方案那样考虑持久化计数器或者分布式唯一ID。只需生成符合格式的字符串即可。 可能的思路是:用date命令获取纳秒部分,因为%N可以给出纳秒,但同系统可能支持同。或者用/dev/urandom生成随机字节,然后用od命令转换成数字。比如: U部分固定,后面9位可以用随机数生成。比如用$RANDOM三次,每次生成3位数,然后拼接。但$RANDOM的范围是0-32767,只能得到最多5位,可能需要调整。 或者使用openssl rand来生成随机字节,然后转换成数字。例如: openssl rand -hex 4 | tr -dc '0-9' | cut -c1-9 过这样可能长度够或者有字母,需要处理。或者用/dev/urandom: tr -dc '0-9' </dev/urandom | head -c 9 这样可以得到9位数字,但可能前面有0,比如U000123456,但用户是否允许以0开头?原示例中的U123456789是9位数,可能有前导零的话也可以,用户没有特别说明允许。 所以可能的命令是: echo "user_id: U$(tr -dc '0-9' </dev/urandom | head -c 9)" 或者用date加上随机数: echo "user_id: U$(date +%s%N | cut -c10-18)" 过date +%s%N会得到秒加纳秒,比如10位秒加9位纳秒,截取中间部分可能得到9位数,但同时间的生成可能会有重复,但用户允许重复,所以没关系。 或者更简单的,用$RANDOM拼接: 比如,三次$RANDOM得到三个数,每个最多5位,但需要补零到3位,然后组合成9位: printf "user_id: U%03d%03d%03d\n" $((RANDOM%1000)) $((RANDOM%1000)) $((RANDOM%1000)) 这样每个部分是0-999,补零到3位,总共9位。但这种方法生成的数字范围是000000000到999999999,可能会有前导零,但符合用户要求的格式。 另外,用户需要的是"user_id": "U123456789"这种格式,所以输出应该包括引号和冒号。例如: echo "\"user_id\": \"U$(tr -dc '0-9' </dev/urandom | head -c 9)\"" 或者使用printf来格式化: printf '"user_id": "U%09d"\n' $((RANDOM%1000000000)) 过$RANDOM的范围是0-32767,所以%09d的话可能前面补零到9位,但实际数值只有最多5位有效数字,后面的都是零。比如$RANDOM是12345,那么会变成000012345,这样可能随机,容易重复。所以这种方法可能太合适。 更好的方法是使用/dev/urandom生成9位数字: U$(tr -dc '0-9' < /dev/urandom | head -c9) 这样每次生成9个随机数字,允许重复。比如: echo "user_id: U$(tr -dc '0-9' < /dev/urandom | head -c9)" 过需要注意,tr -dc '0-9'可能会需要多次读取,直到收集到足够的数字,所以在某些系统上可能效率高,但可以接受。 另外,引用4中提到printf的使用,例如用printf '%s\t %s\t'来格式化输出,可能需要结合这种方法生成各部分。 总结几种可能的shell命令: 1. 使用/dev/urandom和tr生成9位数字: echo "user_id: U$(tr -dc '0-9' < /dev/urandom | head -c9)" 2. 使用date命令的纳秒部分: echo "user_id: U$(date +%N%s | awk '{print substr($1$2,1,9)}')" 过可能需要调整截取的位置,确保得到9位。 3. 使用$RANDOM多次拼接: echo "user_id: U$(printf "%03d%03d%03d" $((RANDOM%1000)) $((RANDOM%1000)) $((RANDOM%1000)))" 这种方法生成的是三个3位数,可能更均匀分布,但范围有限。 用户允许重复,所以以上方法都可以,但需要考虑同方法的效率和可用的环境。例如,某些环境可能没有/dev/urandom,或者tr命令的选项同。 另外,输出的格式需要是"user_id": "U...",所以需要正确转义引号。在shell中,可以使用单引号包裹字符串,内部的双引号需要转义,或者用反斜杠转义。 例如: echo '"user_id": "'U$(tr -dc '0-9' < /dev/urandom | head -c9)'"' 或者: printf '"user_id": "U%09d"\n' $((RANDOM%1000000000)) 但后者的随机足,因为$RANDOM只有32767,所以生成的数字范围有限,前导零较多。 综合来看,使用/dev/urandom的方法更可靠,生成的数字更随机,允许重复,符合用户需求。</think>#### Shell命令生成方法 ##### 基础版本(允许重复值) ```bash # 生成9位随机数字(允许重复) echo "user_id: U$(tr -dc '0-9' < /dev/urandom | head -c9)" ``` ##### 带格式化输出版本 ```bash # 使用printf控制格式 printf '"user_id": "U%09d"\n' $((RANDOM%1000000000)) ``` ##### 时间戳混合随机数 ```bash # 组合纳秒时间戳与随机数(Linux系统适用) echo "user_id: U$(date +%N%s | sha256sum | head -c9 | tr -dc '0-9')" ``` #### 关键参数说明 | 参数 | 作用 | 特点 | |---------------|-------------------------|---------------------| | `/dev/urandom` | 系统级随机数源 | 高质量随机性 | | `tr -dc '0-9'` | 过滤非数字字符 | 保证纯数字输出 | | `head -c9` | 截取前9位字符 | 控制ID长度 | | `$RANDOM` | Bash内置随机变量 | 简单但范围有限(0-32767)| #### 重复生成原理 1. **设置唯一性校验**:直接输出随机结果 2. **使用概率控制**:9位数字总组合数$10^9$,自然重复概率极低但允许存在 3. **随机源选择**:`/dev/urandom`提供系统级熵池支持[^1] #### 应用示例 ```bash # 批量生成10个ID for i in {1..10}; do echo "user_id: U$(tr -dc '0-9' < /dev/urandom | head -c9)" done ``` --相关问题--: 1. 如何确保Shell生成随机数质量? 2. 在低熵环境中如何改进随机数生成? 3. 如何给生成的user_id添加时间戳前缀?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值