茄子在线看片免费人成视频,午夜福利精品a在线观看,国产高清自产拍在线观看,久久综合久久狠狠综合

    <s id="ddbnn"></s>
  • <sub id="ddbnn"><ol id="ddbnn"></ol></sub>

  • <legend id="ddbnn"></legend><s id="ddbnn"></s>

    Shell腳本實現(xiàn)亂序排列文件內(nèi)容的多種方法(洗牌問題)
    來源:易賢網(wǎng) 閱讀:1419 次 日期:2015-01-30 14:12:40
    溫馨提示:易賢網(wǎng)小編為您整理了“Shell腳本實現(xiàn)亂序排列文件內(nèi)容的多種方法(洗牌問題)”,方便廣大網(wǎng)友查閱!

    洗牌問題:洗一副撲克,有什么好辦法?既能洗得均勻,又能洗得快?即相對于一個文件來說怎樣高效率的實現(xiàn)亂序排列?

    ChinaUnix 確實是 Shell 高手云集的地方,只要你想得到的問題,到那里基本上都能找到答案。r2007 給出了一個取巧的方法,利用 Shell 的 $RANDOM 變量給原文件的每一行加上隨機的行號然后根據(jù)這個隨機行號進行排序,再把臨時加上去的行號給過濾掉,這樣操作之后得到的新文件就相當于被隨機“洗”了一次:

    代碼如下:

    while read i;do echo "$i $RANDOM";done<file|sort -k2n|cut -d" " -f1

    當然如果你的源文件每行的內(nèi)容比較復(fù)雜的話就必須對這段代碼進行改寫,但只要知道了處理的關(guān)鍵技巧,剩下的問題都不難解決。

    另外一篇來自蘇蓉蓉的用 awk 來實現(xiàn)洗牌效果的隨機文件排序代碼分析(原貼在這里,以及對此帖的一個后續(xù)討論,如果你沒有登錄帳號的話可以到這里查看精華區(qū)文章)則寫的更為詳細:

    --------------------------------------------------------------------

    關(guān)于洗牌問題,其實已經(jīng)有了一個很好的shell解法,這里另外給三個基于AWK的方法,有錯誤之處還請不吝指出。

    方法一:窮舉

    類似于窮舉法,構(gòu)造一個散列來記錄已經(jīng)打印行出現(xiàn)行的次數(shù),如果出現(xiàn)次數(shù)多于一次則不進行處理,這樣可以防止重復(fù),但缺點是加大了系統(tǒng)的開銷。

    代碼如下:

    awk -v N=`sed -n '$=' data` '

    BEGIN{

    FS="\n";

    RS=""

    }

    {

    srand();

    while(t!=N){

    x=int(N*rand()+1);

    a[x]++;

    if(a[x]==1)

    {

    print $x;t++

    }

    }

    }

    ' data

    方法二:變換

    基于數(shù)組下標變換的辦法,即用數(shù)組儲存每行的內(nèi)容,通過數(shù)組下標的變換交換數(shù)組的內(nèi)容,效率好于方法一。

    代碼如下:

    #! /usr/awk

    BEGIN{

    srand();

    }

    {

    b[NR]=$0;

    }

    END{

    C(b,NR);

    for(x in b)

    {

    print b[x];

    }}

    function C(arr,len,i,j,t,x){

    for(x in arr)

    {

    i=int(len*rand())+1;

    j=int(len*rand())+1;

    t=arr[i];

    arr[i]=arr[j];

    arr[j]=t;

    }

    }

    方法三:散列

    三個方法中最好的。

    利用AWK中散列的特性(詳細請看:info gawk 中的7.x ),只要構(gòu)造一個隨機不重復(fù)的散列函數(shù)即可,因為一個文件每行的linenumber是獨一無二的,所以用:

    隨機數(shù)+每行l(wèi)inenumber ------對應(yīng)------> 那一行的內(nèi)容

    即為所構(gòu)造的隨機函數(shù)。

    從而有:

    代碼如下:

    awk 'BEGIN{srand()}{b[rand()NR]=$0}END{for(x in b)print b[x]}' data

    其實大家擔心的使用內(nèi)存過大的問題不必太在意,可以做一個測試:

    測試環(huán)境:

    PM 1.4GHz CPU,40G硬盤,內(nèi)存256M的LAPTOP

    SUSE 9.3 GNU bash version 3.00.16 GNU Awk 3.1.4

    產(chǎn)生一個五十幾萬行的隨機文件,大約有38M:

    代碼如下:

    od /dev/urandom |dd count=75000 >data

    拿效率較低的方法一來說:

    洗牌一次所用時間:

    代碼如下:

    time awk -v N=`sed -n '$=' data` '

    BEGIN{

    FS="\n";

    RS=""

    }

    {

    srand();

    while(t!=N){

    x=int(N*rand()+1);

    a[x]++;

    if(a[x]==1)

    {

    print $x;t++

    }

    }

    }

    ' data

    結(jié)果(文件內(nèi)容省略):

    代碼如下:

    real 3m41.864s

    user 0m34.224s

    sys 0m2.102s

    所以效率還是勉強可以接受的。

    方法二的測試:

    代碼如下:

    time awk -f awkfile datafile

    結(jié)果(文件內(nèi)容省略):

    代碼如下:

    real 2m26.487s

    user 0m7.044s

    sys 0m1.371s

    效率明顯好于第一個。

    接著考察一下方法三的效率:

    代碼如下:

    time awk 'BEGIN{srand()}{b[rand()NR]=$0}END{for(x in b)print b[x]}' data

    結(jié)果(文件內(nèi)容省略):

    代碼如下:

    real 0m49.195s

    user 0m5.318s

    sys 0m1.301s

    對于一個38M的文件來說已經(jīng)相當不錯了。

    --------------------------------------------------------------------

    附帶存一個來自 flyfly 寫的 python 版本亂序代碼:

    代碼如下:

    #coding:gb2312

    import sys

    import random

    def usage():

    print "usage:program srcfilename dstfilename"

    global filename

    filename = ""

    try:

    filename = sys.argv[1]

    except:

    usage()

    raise()

    #open the phonebook file

    f = open(filename, 'r')

    phonebook = f.readlines()

    print phonebook

    f.close()

    #write to file randomly

    try:

    filename = sys.argv[2]

    except:

    usage()

    raise()

    f = open(filename, 'w')

    random.shuffle(phonebook)

    f.writelines(phonebook)

    f.close()

    更多信息請查看IT技術(shù)專欄

    更多信息請查看腳本欄目

    2026上岸·考公考編培訓(xùn)報班

    • 報班類型
    • 姓名
    • 手機號
    • 驗證碼
    關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點 | 投訴建議
    工業(yè)和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網(wǎng)安備53010202001879號 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號
    聯(lián)系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關(guān)注公眾號:hfpxwx
    咨詢QQ:1093837350(9:00—18:00)版權(quán)所有:易賢網(wǎng)