awk之隨機函數rand()和srand() 分類: LINUX 文件: 1234567 abcdefg ...... 現在想要隨機抽取5列組成下面的內容,允許重復: 36612 cffab ...... 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的隨機值作為字段打印出來。 #!/bin/bash len="5" while read line; do str="" while [ "${#str}" -lt "$len" ]; do letter="${line:$(($RANDOM%${#line})):1}" str="$str$letter" done echo $str 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后就打印出該行。 謝謝Tim和shell_HAT的精彩代碼。
