使用bash脚本快速生成测试数据(uuid、大随机数等)

使用bash脚本快速生成测试数据(uuid、大随机数等),bash,Bash,我有一个小bash脚本,其中有一个函数,其中包含一个case语句,如果第一个参数与case参数匹配,该语句将回显随机数据。 代码如下: #!/usr/bin/env bash ' AC='auto-increment' UUID='uuid'

我有一个小bash脚本,其中有一个函数,其中包含一个case语句,如果第一个参数与case参数匹配,该语句将回显随机数据。 代码如下:

#!/usr/bin/env bash   '

AC='auto-increment'                                                                                                    
UUID='uuid'                                                                                                            
LAT='lat'                                                                                                              
LONG='long'                                                                                                            
IP='ip'

generate_mock_data() {                                                                                                 
# ARGS: $1 - data type, $2 - loop index                                                                              
case ${1} in                                                                                                         
    ${AC})                                                                                                             
        echo ${2} ;;                                                                                                     
    ${UUID})                                                                                                           
        uuidgen ;;                                                                                                       
    ${LAT})                                                                                                            
        echo $((RANDOM % 180 - 90)).$(shuf -i1000000-9999999 -n1) ;;                                                     
    ${LONG})                                                                                                           
        echo $((RANDOM % 360 - 180)).$(shuf -i1000000-9999999 -n1) ;;                                                    
    ${IP})                                                                                                             
        echo $((RANDOM%256)).$((RANDOM%256)).$((RANDOM%256)).$((RANDOM%256)) ;;                                          
esac                                                                                                                 
}

# Writing data to file                                             
headers=('auto-increment' 'uuid' 'lat' 'long' 'ip')                
for i in {1..2500}; do                                             
  for header in "${headers[@]}"; do                                
    echo -n $(generate_mock_data ${header} ${i}),                  
  done                                                             
echo  # New line                                                 
done >> file.csv
但是,仅2500行的执行时间非常慢:

real 0m8.876s
用户0m0.576s
系统0m0.868s

我做错了什么?我能做些什么来加快这个过程吗?或者bash不是适合这些类型操作的语言?
我还尝试分析整个脚本,但在查看日志后,我没有发现任何明显的瓶颈

似乎你可以用Python快速生成UUID,所以如果你只执行一次Python就可以生成2500个UUID,而你不是Python程序员——就像我一样;-)然后,您可以使用
awk
对其进行修补:

python -c 'import uuid; print("\n".join([str(uuid.uuid4()).upper() for x in range(2500)]))' |
   awk '{
      lat=-90+180*rand();
      lon=-180+360*rand();
      ip=int(256*rand()) "." int(256*rand()) "." int(256*rand()) "." int(256*rand());
      print NR,$0,lat,lon,ip
  }' OFS=,
这在我的iMac上需要0.06秒

  • OFS
    是“输出字段分隔符”
  • NR
    是行号
  • $0表示“整个输入行”
您可以自己尝试Python,如下所示:

python -c 'import uuid; print("\n".join([str(uuid.uuid4()).upper() for x in range(2500)]))'

似乎你可以用Python快速生成UUID,所以如果你只执行一次Python就可以生成2500个UUID,而你不是Python程序员——像我一样;-)然后,您可以使用
awk
对其进行修补:

python -c 'import uuid; print("\n".join([str(uuid.uuid4()).upper() for x in range(2500)]))' |
   awk '{
      lat=-90+180*rand();
      lon=-180+360*rand();
      ip=int(256*rand()) "." int(256*rand()) "." int(256*rand()) "." int(256*rand());
      print NR,$0,lat,lon,ip
  }' OFS=,
这在我的iMac上需要0.06秒

  • OFS
    是“输出字段分隔符”
  • NR
    是行号
  • $0表示“整个输入行”
您可以自己尝试Python,如下所示:

python -c 'import uuid; print("\n".join([str(uuid.uuid4()).upper() for x in range(2500)]))'
Shell是正确的工具吗? 不太可能,但如果你避免不良行为,你可以相对快速地做出一些事情

使用ksh93,以下设备在0.5-0.6s的挂钟中可靠运行;对于bash,1.2-1.3s

它看起来像什么?
#/usr/bin/env bash
#显然,如果使用ksh93运行,请对这两行进行注释。:)
[-z“$BASH_VERSION”]&&{echo“这需要BASH 4.1或更高版本”>&2;退出1;}
[[$BASH_VERSION=[123].]&&&{echo“这需要BASH 4.1或更高版本”>&2;退出1;}
uuid_流(){
python-c'
导入uuid
尝试:
尽管如此:
打印str(uuid.uuid4()).upper()
除IOError外:
过了,可能是因为我们关门了。
'
}
#生成一个文件描述符,该描述符发出一个无序的整数流
exec{large_int_fd}
使用ksh93,以下设备在0.5-0.6s的挂钟中可靠运行;对于bash,1.2-1.3s

它看起来像什么?
#/usr/bin/env bash
#显然,如果使用ksh93运行,请对这两行进行注释。:)
[-z“$BASH_VERSION”]&&{echo“这需要BASH 4.1或更高版本”>&2;退出1;}
[[$BASH_VERSION=[123].]&&&{echo“这需要BASH 4.1或更高版本”>&2;退出1;}
uuid_流(){
python-c'
导入uuid
尝试:
尽管如此:
打印str(uuid.uuid4()).upper()
除IOError外:
过了,可能是因为我们关门了。
'
}
#生成一个文件描述符,该描述符发出一个无序的整数流

exec{large_int_fd}<您在8.9秒内启动了1500个进程。。。调用
生成模拟数据
运行外部程序的五分之三;该程序需要从磁盘(或者更可能是缓存)加载、初始化,然后运行到完成。
echo$(…)
只是编写
的漫长过程。让函数使用
echo-n
(或者最好是
printf
)来输出不带换行符的字符串;您总是为每个标题项调用一次
generate\u mock\u data
;只需让每个all输出一整行,而不是单独调用它5次;然后您将有一个单独的进程来生成每一行,每一行只需额外调用一个
uuidgen
。您真的需要
uuidgen
吗?我的系统需要8秒来生成2500个uuid,而不做任何其他事情。其他形式的随机数可以接受吗?您已经在8.9秒内启动了1500个进程。。。调用
生成模拟数据
运行外部程序的五分之三;该程序需要从磁盘(或者更可能是缓存)加载、初始化,然后运行到完成。
echo$(…)
只是编写
的漫长过程。让函数使用
echo-n
(或者最好是
printf
)来输出不带换行符的字符串;您总是为每个标题项调用一次
generate\u mock\u data
;只需让每个all输出一整行,而不是单独调用它5次;然后您将有一个单独的进程来生成每一行,每一行只需额外调用一个
uuidgen
。您真的需要
uuidgen
吗?我的系统需要8秒来生成2500个uuid,而不做任何其他事情。可以接受其他形式的随机数吗?很好。我正要编写一个优化的bash实现,但看到了
shuf
uuidgen
,决定不值得花时间——这是一个实用、可靠、可读的替代方案。(好吧——不值得花时间,但我无论如何都在这么做。不过,这是一个非常好的答案。))我要感谢你们两位好心的先生的帮助。我之所以接受Mark的答案,只是因为它赢得了速度测试——生成100K行所需的时间不到1.3秒,这与Charles用+-19s.Nice编写的精练bash脚本相比几乎没有差别。我正要编写一个优化的bash实现,但看到了
shuf
uuidgen
,决定不值得花时间——这是一个实用、可靠、可读的替代方案。(好吧——不值得花时间,但我无论如何都在这么做。不过,这是一个非常好的答案。))我要感谢你们两位好心的先生的帮助。我