最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Shell腳本實現(xiàn)亂序排列文件內(nèi)容的多種方法(洗牌問題)

 更新時間:2015年01月27日 09:17:45   投稿:junjie  
這篇文章主要介紹了Shell腳本實現(xiàn)亂序排列文件內(nèi)容的多種方法(洗牌問題),本文給出3個Shell腳本和一個Python腳本解決亂序排列文件內(nèi)容問題,需要的朋友可以參考下

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

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

復(fù)制代碼 代碼如下:

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

當(dāng)然如果你的源文件每行的內(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)的開銷。

復(fù)制代碼 代碼如下:

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)容,效率好于方法一。

復(fù)制代碼 代碼如下:

#! /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ù)。
    從而有:

復(fù)制代碼 代碼如下:

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

    其實大家擔(dān)心的使用內(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:

復(fù)制代碼 代碼如下:

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

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

洗牌一次所用時間:

復(fù)制代碼 代碼如下:

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)容省略):
復(fù)制代碼 代碼如下:

real    3m41.864s
user    0m34.224s
sys     0m2.102s

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

方法二的測試:

復(fù)制代碼 代碼如下:

time awk -f awkfile datafile

結(jié)果(文件內(nèi)容省略):
復(fù)制代碼 代碼如下:

real    2m26.487s
user    0m7.044s
sys     0m1.371s

效率明顯好于第一個。

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

復(fù)制代碼 代碼如下:

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

結(jié)果(文件內(nèi)容省略):
復(fù)制代碼 代碼如下:

real    0m49.195s
user    0m5.318s
sys     0m1.301s

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

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

復(fù)制代碼 代碼如下:

#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()

相關(guān)文章

  • 5個實用的shell腳本面試題和答案

    5個實用的shell腳本面試題和答案

    這篇文章主要介紹了5個實用的shell腳本面試題和答案,給出的腳本堪稱編碼規(guī)范,麻雀雖小,異常處理,友好提示,一應(yīng)俱全,值得學(xué)習(xí),需要的朋友可以參考下
    2014-06-06
  • Shell腳本傳遞參數(shù)的3種方法比較

    Shell腳本傳遞參數(shù)的3種方法比較

    這篇文章主要介紹了Shell腳本傳遞參數(shù)的3種方法比較,本文直接給出代碼示例,在代碼中包含詳細注解,需要的朋友可以參考下
    2015-05-05
  • Shell腳本中計算字符串長度的5種方法

    Shell腳本中計算字符串長度的5種方法

    這篇文章主要介紹了Shell腳本中計算字符串長度的5種方法,來自于個人Shell腳本長期的開發(fā)經(jīng)驗,需要的朋友可以參考下
    2014-06-06
  • Shell腳本一鍵安裝Nginx服務(wù)自定義Nginx版本

    Shell腳本一鍵安裝Nginx服務(wù)自定義Nginx版本

    這篇文章主要為大家介紹了Shell腳本一鍵安裝Nginx服務(wù),用戶可自定義Nginx版本的腳本示例,有需要的朋友可以借鑒參考下,希望能夠參考下
    2022-03-03
  • Linux Shell制作錄制回放功能腳本

    Linux Shell制作錄制回放功能腳本

    這篇文章主要為大家詳細介紹了Linux Shell制作錄制回放功能腳本,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Linux 中的nc命令小結(jié)

    Linux 中的nc命令小結(jié)

    這篇文章主要介紹了linux中的nc命令知識,非常不錯,值得收藏,需要的朋友參考下吧
    2017-02-02
  • shell腳本實現(xiàn)拷貝大文件顯示百分比的代碼分享

    shell腳本實現(xiàn)拷貝大文件顯示百分比的代碼分享

    這篇文章主要介紹了shell腳本實現(xiàn)拷貝大文件顯示百分比的代碼分享,需要的朋友可以參考下
    2014-08-08
  • shell腳本echo輸出不換行功能增強實例

    shell腳本echo輸出不換行功能增強實例

    這個腳本很簡單,就是可以用3種不同的函數(shù)(方法)來實現(xiàn),輸出后不換行
    2016-08-08
  • shell自動拉取鏡像并運行容器的shell腳本

    shell自動拉取鏡像并運行容器的shell腳本

    本文主要介紹了shell自動拉取鏡像并運行容器的shell腳本,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • 詳解如何在Linux中退出Hive命令行

    詳解如何在Linux中退出Hive命令行

    在使用Hive進行數(shù)據(jù)查詢和操作時,有時候我們需要退出Hive命令行界面,本文將介紹如何在Linux系統(tǒng)中退出Hive命令行,文中通過代碼示例講解的非常詳細,具有一定的參考價值,需要的朋友可以參考下
    2024-11-11

最新評論

铜山县| 灌南县| 乡宁县| 大安市| 乌兰县| 平和县| 碌曲县| 外汇| 资溪县| 安陆市| 阿坝| 炎陵县| 宜州市| 鹿泉市| 江孜县| 德钦县| 江陵县| 莒南县| 昭苏县| 犍为县| 汉川市| 昭觉县| 玉溪市| 佛学| 凌海市| 年辖:市辖区| 汤原县| 大足县| 礼泉县| 新泰市| 蓝田县| 江西省| 万年县| 台南市| 循化| 长海县| 三原县| 左贡县| 南投县| 桂东县| 泾源县|