awk之隨機函式rand()和srand()

germany006發表於2015-01-18
轉載地址:http://blog.chinaunix.net/uid-10540984-id-2942041.html

檔案:
1234567
abcdefg
......

現在想要隨機抽取5列組成下面的內容,允許重複:
36612
cffab
......


  1. awk -F '' 'BEGIN{srand();for(i=1;i<=5;i++)a[i]=int(rand()*100%7+1)}{for(i=1;i<=5;i++)printf $a[i];printf RS}' file
[解析]
思路是首先把FS設定為空,隨機抽取5列,那麼在BEGIN模組定義陣列a中1~5的下標對應隨機的1~7的值,在讀行時把陣列a的值(這是個1~7的隨機值)作為欄位列印出來,這樣就實現了隨機抽取7個欄位中的5個欄位重新組成新的行。 
rand()函式是隨機產生一個0到1之間的保留小數點後6位的小數值,例如0.217788,所以需要乘以100得到21.7788,然後再對7取餘,結果是0.7788,int()取整是0了,我們要獲得1~7的隨機數,所以加1,整個表示式才是 int(rand()*100%7+1) ,其實 int(length*rand()+1) 也是可以得到1~7的隨機數的,只是在BEGIN中,length函式還是為0,這樣就得到了肯定產生於1~7之間的隨機數,問題在於rand()只產生一次,怎麼讓它滾動起來呢?這裡我們還需要srand()函式,括號內沒有表示式的話,它會採用當前時間作為隨機計數器的種子,這樣以秒為間隔,隨機數就能滾動隨機生成了。最後再對應陣列a的隨機值作為欄位列印出來。




  1. #!/bin/bash
  2. len="5"
  3. while read line; do
  4.     str=""
  5.     while [ "${#str}" -lt "$len" ]; do
  6.         letter="${line:$(($RANDOM%${#line})):1}"
  7.         str="$str$letter"
  8.     done
  9.     echo $str
  10. done < file
[解析]
同樣,這個shell指令碼也能實現該功能,首先定義變數 len=5 ,因為只需要5列嘛。然後從file檔案中讀入一行內容給變數 line ,定義一個長度為0的變數 str ,當 str 變數長度大於等於5了,就不再會繼續whlie迴圈,然後列印該變數,在bash中 ${#var} 就是獲取變數的長度,我們再看看怎麼實現的隨機,該shell的原理是讀取 line 變數的隨機0~6位置長度為1的字元,環境變數RANDOM,範圍是0~32767,RANDOM對7取餘的結果是0~6,就能隨機抽取長度為7的字串中的任意一個字元,然後把該字元累計給變數 str ,滿足長度5後就列印出該行。




總結使用方法:
如果得到隨機的字串,長度和字串中出現的字元表可定義,並將字串倒序顯示,如把0123456789 作為基準的字串字元表,產生一個6 位的字串642031,列印出的字串為
130246,可使用bash/perl/php/c 任意一種.


[root@520 test]# awk -v count=6 'BEGIN {srand();str="0123456789";len=length(str);for(i=count;i>0;i--) marry[i]=substr(str,int(rand()*len),1);for(i=count;i>0;i--) printf("%c",marry[i]);printf("\n");for (i=0;i<=count;i++) printf("%c",marry[i]);printf("\n")}'
743013
310347

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28371090/viewspace-1405803/,如需轉載,請註明出處,否則將追究法律責任。

相關文章