ฉันจะสลับบรรทัดของไฟล์ข้อความในบรรทัดคำสั่ง Unix หรือในเชลล์สคริปต์ได้อย่างไร


285

ฉันต้องการสับเปลี่ยนบรรทัดไฟล์ข้อความแบบสุ่มและสร้างไฟล์ใหม่ ไฟล์อาจมีหลายพันบรรทัด

ฉันจะทำอย่างนั้นด้วยcat, awk, cutetc?



ใช่มีคำตอบที่ดีอื่น ๆ ในคำถามเดิมเช่นกัน
Ruggiero Spearman

เป็นเช่นนั้นคุณสร้างรายการคำ wpa หรือไม่ (เพียงเดาแบบสุ่ม)
thahgr

คำตอบ:


360

shufคุณสามารถใช้ อย่างน้อยในบางระบบ (ดูเหมือนไม่มีใน POSIX)

ในฐานะที่เป็น jleedev ชี้ให้เห็น: sort -Rอาจเป็นตัวเลือก อย่างน้อยในบางระบบ ดีคุณจะได้รับภาพ มันได้รับการชี้ให้เห็นว่าsort -Rไม่ได้โดดสับ แต่แทนที่จะเรียงลำดับรายการตามค่าแฮชของพวกเขา

[หมายเหตุจากบรรณาธิการ: sort -R เกือบจะเป็นแบบสับยกเว้นปุ่มที่เรียงลำดับ / เรียงลำดับที่ซ้ำกันจะอยู่ติดกันเสมอ กล่าวอีกนัยหนึ่ง: เฉพาะกับบรรทัด / คีย์อินพุตที่ไม่ซ้ำกันเท่านั้นจึงเป็นการสลับที่แท้จริง แม้ว่าจะเป็นความจริงที่ว่าลำดับเอาต์พุตจะถูกกำหนดโดยค่าแฮชการสุ่มมาจากการเลือกฟังก์ชั่นแฮชแบบสุ่ม- ดูด้วยตนเอง ]


31
shufและsort -Rแตกต่างกันเล็กน้อยเพราะsort -Rสุ่มสั่งองค์ประกอบตามแฮชของพวกเขาซึ่งก็คือsort -Rจะทำให้องค์ประกอบที่ซ้ำกันเข้าด้วยกันในขณะที่shufสับองค์ประกอบทั้งหมดแบบสุ่ม
SeMeKh

146
สำหรับผู้ใช้ OS X: brew install coreutilsจากนั้นใช้gshuf ...(:
ELLIOTTCABLE

15
sort -Rและshufควรถูกมองว่าแตกต่างอย่างสิ้นเชิง sort -Rไม่แน่นอน หากคุณโทรหาสองครั้งในเวลาที่ต่างกันในอินพุตเดียวกันคุณจะได้รับคำตอบเดียวกัน shufในทางกลับกันจะสร้างเอาต์พุตแบบสุ่มดังนั้นจึงมีแนวโน้มที่จะให้เอาต์พุตที่แตกต่างกันในอินพุตเดียวกัน
EfForEffort

18
นั่นไม่ถูกต้อง "sort -R" ใช้แฮชคีย์สุ่มที่แตกต่างกันในแต่ละครั้งที่คุณเรียกใช้ดังนั้นจึงสร้างเอาต์พุตที่แตกต่างกันในแต่ละครั้ง
Mark Pettit

3
หมายเหตุเกี่ยวกับการสุ่ม: ตามเอกสาร GNU "โดยค่าเริ่มต้นคำสั่งเหล่านี้ใช้เครื่องกำเนิดไฟฟ้าแบบหลอกหลอกภายในเริ่มต้นด้วยจำนวนเล็กน้อยของเอนโทรปี แต่สามารถนำไปใช้แหล่งภายนอกที่มีตัวเลือกไฟล์ --random-source ="
Royce Williams

86

Perl one-liner จะเป็นวิธีแก้ปัญหาแบบง่าย ๆ ของ Maxim

perl -MList::Util=shuffle -e 'print shuffle(<STDIN>);' < myfile

6
ฉันใช้นามแฝงนี้เพื่อสับเปลี่ยนใน OS X ขอบคุณ!
แมว Unfun

นี่เป็นสคริปต์เดียวในหน้านี้ที่ส่งคืนสายสุ่มจริง โซลูชัน awk อื่น ๆ มักพิมพ์ผลลัพธ์ที่ซ้ำกัน
Felipe Alvarez

1
แต่ต้องระวังเพราะในออกมาคุณจะหายไปหนึ่งบรรทัด :) มันก็จะเข้าร่วมกับสายอื่น :)
JavaRunner

@ JavaRunner: ฉันคิดว่าคุณกำลังพูดถึงการป้อนข้อมูลโดยไม่ต้องต่อท้าย\n; ใช่ว่า\nจะต้องนำเสนอ - และมันมักจะเป็น - มิฉะนั้นคุณจะได้รับสิ่งที่คุณอธิบาย
mklement0

1
รัดกุมอย่างน่าอัศจรรย์ ฉันขอแนะนำให้แทนที่<STDIN>ด้วย<>ดังนั้นโซลูชันจึงทำงานกับอินพุตจากไฟล์ด้วย
mklement0

60

คำตอบนี้เติมเต็มคำตอบที่มีอยู่มากมายด้วยวิธีต่อไปนี้:

  • คำตอบที่มีอยู่ถูกบรรจุในฟังก์ชันเชลล์ที่ยืดหยุ่น :

    • ฟังก์ชั่นนี้ไม่เพียงstdinป้อนข้อมูลเข้าเท่านั้นแต่ยังมีอาร์กิวเมนต์ชื่อไฟล์หรือ
    • ฟังก์ชั่นนี้ใช้ขั้นตอนพิเศษในการจัดการSIGPIPEในลักษณะปกติ (การยกเลิกแบบเงียบด้วยรหัสทางออก141) ซึ่งแตกต่างจากเสียงดัง headนี้เป็นสิ่งสำคัญเมื่อท่อส่งออกฟังก์ชั่นกับท่อที่ปิดให้บริการในช่วงต้นเช่นเมื่อท่อไป
  • เปรียบเทียบประสิทธิภาพจะทำ


shuf() { awk 'BEGIN {srand(); OFMT="%.17f"} {print rand(), $0}' "$@" |
               sort -k1,1n | cut -d ' ' -f2-; }
shuf() { perl -MList::Util=shuffle -e 'print shuffle(<>);' "$@"; }
shuf() { python -c '
import sys, random, fileinput; from signal import signal, SIGPIPE, SIG_DFL;    
signal(SIGPIPE, SIG_DFL); lines=[line for line in fileinput.input()];   
random.shuffle(lines); sys.stdout.write("".join(lines))
' "$@"; }

ดูส่วนด้านล่างสำหรับฟังก์ชั่นเวอร์ชั่นWindows

shuf() { ruby -e 'Signal.trap("SIGPIPE", "SYSTEM_DEFAULT");
                     puts ARGF.readlines.shuffle' "$@"; }

การเปรียบเทียบประสิทธิภาพ:

หมายเหตุ: ตัวเลขเหล่านี้ได้รับใน iMac ปลายปี 2012 กับ 3.2 GHz Intel Core i5 และ Fusion Drive โดยใช้ OSX 10.10.3 ในขณะที่การกำหนดเวลาจะแตกต่างกันไปตามระบบปฏิบัติการที่ใช้รายละเอียดเครื่องawkการใช้งาน (เช่นawkรุ่นBSD ที่ใช้บน OSX มักจะช้ากว่า GNU awkและโดยเฉพาะอย่างยิ่งmawk) สิ่งนี้ควรให้ความรู้สึกทั่วไปของประสิทธิภาพที่สัมพันธ์กัน

ป้อนข้อมูลไฟล์เป็นไฟล์ 1 ล้านเส้นseq -f 'line %.0f' 1000000ผลิตด้วย
เวลาจะถูกเรียงตามลำดับจากน้อยไปหามาก (เร็วที่สุดก่อน):

  • shuf
    • 0.090s
  • ทับทิม 2.0.0
    • 0.289s
  • Perl 5.18.2
    • 0.589s
  • หลาม
    • 1.342sด้วย Python 2.7.6; 2.407s(!) ด้วย Python 3.4.2
  • awk+ sort+cut
    • 3.003sกับ BSD awk; 2.388sกับ GNU awk(4.1.1); 1.811sด้วยmawk(1.3.4);

สำหรับการเปรียบเทียบเพิ่มเติมโซลูชั่นที่ไม่ได้บรรจุเป็นฟังก์ชันข้างต้น:

  • sort -R (ไม่ใช่การสลับที่แท้จริงถ้ามีสายอินพุตที่ซ้ำกัน)
    • 10.661s - การจัดสรรหน่วยความจำเพิ่มเติมดูเหมือนจะไม่สร้างความแตกต่าง
  • สกาล่า
    • 24.229s
  • bash ลูป + sort
    • 32.593s

บทสรุป :

  • ใช้shufถ้าทำได้ - เร็วที่สุด
  • ทับทิมไม่ดีตามมาด้วยPerl
  • Pythonช้ากว่า Ruby และ Perl อย่างเห็นได้ชัดและเมื่อเปรียบเทียบกับ Python เวอร์ชั่น 2.7.6 นั้นเร็วกว่า 3.4.1 เล็กน้อย
  • ใช้ POSIX สอดคล้องawk+ sort+ cutคำสั่งผสมเป็นที่พึ่งสุดท้าย ; ซึ่งawkการดำเนินการที่คุณใช้เรื่อง ( mawkจะเร็วกว่า GNU awk, BSD awkเป็นที่ช้าที่สุด)
  • อยู่ห่างจากsort -R, bashลูปและสกาลา

ของ Windowsรุ่นของงูหลามวิธีการแก้ปัญหา (รหัสงูหลามเป็นเหมือนกันยกเว้นสำหรับรูปแบบในการเสนอราคาและการกำจัดของงบสัญญาณที่เกี่ยวข้องกับการที่ไม่ได้รับการสนับสนุนบนวินโดวส์):

  • สำหรับ PowerShell (ใน Windows PowerShell คุณจะต้องปรับ$OutputEncodingถ้าคุณต้องการส่งอักขระที่ไม่ใช่ ASCII ผ่านไปป์ไลน์):
# Call as `shuf someFile.txt` or `Get-Content someFile.txt | shuf`
function shuf {
  $Input | python -c @'
import sys, random, fileinput;
lines=[line for line in fileinput.input()];
random.shuffle(lines); sys.stdout.write(''.join(lines))
'@ $args  
}

โปรดทราบว่า PowerShell สามารถสับเปลี่ยนผ่านGet-Randomcmdlet ได้อย่างเป็นธรรมชาติ (แม้ว่าประสิทธิภาพอาจมีปัญหา) เช่น:
Get-Content someFile.txt | Get-Random -Count ([int]::MaxValue)

  • สำหรับcmd.exe(ไฟล์แบตช์):

บันทึกลงไฟล์shuf.cmdเช่น:

@echo off
python -c "import sys, random, fileinput; lines=[line for line in fileinput.input()]; random.shuffle(lines); sys.stdout.write(''.join(lines))" %*

SIGPIPE ไม่มีอยู่ใน Windows ดังนั้นฉันจึงใช้ one-liner แบบง่าย ๆ แทน:python -c "import sys, random; lines = [x for x in sys.stdin.read().splitlines()] ; random.shuffle(lines); print(\"\n\".join([line for line in lines]));"
23419

@ elig: ขอบคุณ แต่การไม่from signal import signal, SIGPIPE, SIG_DFL; signal(SIGPIPE, SIG_DFL);ใช้โซลูชันเดิมนั้นเพียงพอและยังคงความยืดหยุ่นในการส่งผ่านอาร์กิวเมนต์ชื่อไฟล์- ไม่จำเป็นต้องเปลี่ยนสิ่งอื่นใด (ยกเว้นการอ้างอิง) - โปรดดูหัวข้อใหม่ที่เพิ่มไว้ใน ด้านล่าง.
mklement0

27

ฉันใช้สคริปต์ Perl เล็ก ๆ ซึ่งฉันเรียกว่า "unsort":

#!/usr/bin/perl
use List::Util 'shuffle';
@list = <STDIN>;
print shuffle(@list);

ฉันยังมีเวอร์ชันที่คั่นด้วย NULL ที่เรียกว่า "unsort0" ... มีประโยชน์สำหรับใช้กับ find -print0 เป็นต้น

PS: โหวตขึ้น 'shuf' ด้วยฉันไม่รู้ว่าอยู่ใน coreutils ในวันนี้ ... ข้างต้นอาจยังมีประโยชน์หากระบบของคุณไม่มี 'shuf'


คนดี RHEL 5.6 ไม่มี shuf (
Maxim Egorushkin

1
ทำได้ดีมาก ฉันขอแนะนำให้แทนที่<STDIN>ด้วย<>เพื่อให้โซลูชันทำงานกับอินพุตจากไฟล์ด้วย
mklement0

20

นี่คือความพยายามครั้งแรกที่ง่ายใน coder แต่ยากใน CPU ซึ่งเตรียมหมายเลขสุ่มให้กับแต่ละบรรทัดเรียงลำดับแล้วดึงแถบตัวเลขสุ่มจากแต่ละบรรทัด ผลจะถูกเรียงลำดับแบบสุ่ม:

cat myfile | awk 'BEGIN{srand();}{print rand()"\t"$0}' | sort -k1 -n | cut -f2- > myfile.shuffled

8
UUOC ส่งไฟล์ให้ awk เอง
ghostdog74

1
head myfile | awk ...ขวาผมแก้ปัญหาด้วย จากนั้นฉันก็เปลี่ยนเป็นแมว นั่นคือเหตุผลที่มันถูกทิ้งไว้ที่นั่น
Ruggiero Spearman

ไม่จำเป็นต้อง-k1 -nเรียงลำดับเนื่องจากผลลัพธ์ของ awk rand()นั้นเป็นทศนิยมระหว่าง 0 ถึง 1 และเพราะสิ่งที่สำคัญคือมันได้รับการจัดเรียงใหม่อย่างใด -k1อาจช่วยเร่งความเร็วโดยไม่สนใจส่วนที่เหลือของบรรทัดแม้ว่าเอาต์พุตของ rand () ควรไม่ซ้ำกันมากพอที่จะเปรียบเทียบการลัดวงจร
bonsaiviking

@ ghostdog74: การใช้แมวที่ไร้ประโยชน์ส่วนใหญ่นั้นมีประโยชน์จริง ๆ เพราะมีความสอดคล้องกันระหว่างคำสั่ง piped และไม่ใช่ ดีกว่าที่จะรักษาcat filename |(หรือ< filename |) กว่าจำไว้ว่าแต่ละโปรแกรมใช้เวลาใส่ไฟล์ (หรือไม่)
ShreevatsaR

2
shuf () {awk 'BEGIN {srand ()} {print rand () "\ t" $ 0}' "$ @" | จัดเรียง | cut -f2-;}
Meow

16

นี่คือสคริปต์ awk

awk 'BEGIN{srand() }
{ lines[++d]=$0 }
END{
    while (1){
    if (e==d) {break}
        RANDOM = int(1 + rand() * d)
        if ( RANDOM in lines  ){
            print lines[RANDOM]
            delete lines[RANDOM]
            ++e
        }
    }
}' file

เอาท์พุต

$ cat file
1
2
3
4
5
6
7
8
9
10

$ ./shell.sh
7
5
10
9
6
8
2
1
3
4

ทำอย่าง แต่ในทางปฏิบัติได้ช้ากว่าคำตอบของตัวเองของ OPซึ่งรวมawkกับและsort cutสำหรับไม่เกินหลายพันบรรทัดมันไม่ได้สร้างความแตกต่างมากนัก แต่เมื่อนับจำนวนบรรทัดที่สูงขึ้นมันก็สำคัญ (เกณฑ์ขึ้นอยู่กับawkการใช้งาน) ทำให้เข้าใจง่ายขึ้นเล็กน้อยที่จะเปลี่ยนสายwhile (1){และมีif (e==d) {break} while (e<d)
mklement0

11

หนึ่งซับสำหรับหลาม:

python -c "import random, sys; lines = open(sys.argv[1]).readlines(); random.shuffle(lines); print ''.join(lines)," myFile

และสำหรับการพิมพ์เพียงหนึ่งบรรทัดสุ่ม:

python -c "import random, sys; print random.choice(open(sys.argv[1]).readlines())," myFile

แต่เห็นโพสต์นี้random.shuffle()สำหรับข้อเสียของงูหลามของ มันใช้งานไม่ได้กับองค์ประกอบหลายอย่าง (มากกว่า 2080)


2
"drawback" ไม่เฉพาะเจาะจงกับ Python รอบระยะเวลา PRNG ที่ จำกัด สามารถแก้ไขได้ด้วยการป้อนข้อมูล PRNG อีกครั้งด้วยเอนโทรปีจากระบบเช่น/dev/urandomนั้น random.SystemRandom().shuffle(L)ที่จะใช้ประโยชน์จากงูหลาม:
jfs

ไม่ต้องเข้าร่วม () ต้องเป็น '\ n' เพื่อให้บรรทัดพิมพ์แต่ละบรรทัดด้วยตนเอง
Elig

@elig: ไม่เพราะ.readLines()ส่งคืนบรรทัดด้วยการขึ้นบรรทัดใหม่
mklement0

9

ฟังก์ชั่นที่ใช้ awk แบบง่ายจะทำงาน:

shuffle() { 
    awk 'BEGIN{srand();} {printf "%06d %s\n", rand()*1000000, $0;}' | sort -n | cut -c8-
}

การใช้งาน:

any_command | shuffle

สิ่งนี้ควรใช้ได้กับ UNIX เกือบทุกชนิด ทดสอบบน Linux, Solaris และ HP-UX

ปรับปรุง:

โปรดทราบว่าเลขศูนย์นำหน้า ( %06d) และการrand()คูณทำให้ทำงานได้อย่างถูกต้องในระบบที่sortไม่เข้าใจตัวเลข มันสามารถจัดเรียงตามคำสั่งพจนานุกรม (aka การเปรียบเทียบสตริงปกติ)


ความคิดที่ดีในการจัดทำแพ็กเกจคำตอบของ OP เองเป็นฟังก์ชั่น หากคุณผนวก"$@"มันจะทำงานกับไฟล์เป็นอินพุต ไม่มีเหตุผลที่จะทวีคูณrand()เพราะsort -nสามารถแยกเศษส่วนทศนิยมได้ มันเป็น แต่เป็นความคิดที่ดีในการควบคุมawkรูปแบบการออก 's เพราะมีรูปแบบเริ่มต้น%.6g, rand()ออกจะจำนวนครั้งคราวในการชี้แจงสัญกรณ์ ในขณะที่การสับเปลี่ยนได้สูงถึง 1 ล้านบรรทัดนั้นเพียงพอในทางปฏิบัติมันเป็นเรื่องง่ายที่จะสนับสนุนไลน์เพิ่มเติมโดยไม่ต้องจ่ายค่าปรับประสิทธิภาพมากนัก %.17fเช่น
mklement0

1
@ mklement0 ฉันไม่ได้สังเกตเห็นคำตอบของ OPs ในขณะที่เขียนของฉัน แรนด์ () คูณด้วย 10e6 เพื่อให้ทำงานกับโซลาริสหรือ HPux เรียงลำดับเท่าที่ฉันจำได้ ความคิดที่ดีกับ "$ @"
MichałŠrajer

1
เข้าใจแล้วขอบคุณ บางทีคุณอาจเพิ่มเหตุผลนี้เพื่อการคูณกับคำตอบนั้น โดยทั่วไปตาม POSIX sortควรจะสามารถจัดการเศษส่วนทศนิยม (แม้จะมีตัวคั่นหลายพันตามที่ฉันเพิ่งสังเกตเห็น)
mklement0

7

ทับทิม FTW:

ls | ruby -e 'puts STDIN.readlines.shuffle'

1
สิ่งที่ยอดเยี่ยม; หากคุณใช้puts ARGF.readlines.shuffleคุณสามารถทำให้มันใช้ได้กับทั้งอินพุต stdin และอาร์กิวเมนต์ชื่อไฟล์
mklement0

ยิ่งสั้นruby -e 'puts $<.sort_by{rand}'- ARGF สามารถนับได้แล้วดังนั้นเราจึงสามารถสับเปลี่ยนบรรทัดได้โดยการจัดเรียงตามค่าสุ่ม
akuhn

6

หนึ่งซับสำหรับไพ ธ อนตามคำตอบของ scaiแต่ a) ใช้ stdin, b) ทำให้ผลลัพธ์ซ้ำกับเมล็ด c) เลือกเพียง 200 ของบรรทัดทั้งหมด

$ cat file | python -c "import random, sys; 
  random.seed(100); print ''.join(random.sample(sys.stdin.readlines(), 200))," \
  > 200lines.txt

6

shufที่เรียบง่ายและใช้งานง่ายวิธีที่จะใช้

ตัวอย่าง:

ถือว่าwords.txtเป็น:

the
an
linux
ubuntu
life
good
breeze

หากต้องการสลับบรรทัดให้ทำ:

$ shuf words.txt

ซึ่งจะโยนเส้นสับเพื่อออกมาตรฐาน ; ดังนั้นคุณต้องไพพ์มันไปที่ไฟล์เอาต์พุตเช่น:

$ shuf words.txt > shuffled_words.txt

การสลับแบบสุ่มหนึ่งครั้งอาจทำให้:

breeze
the
linux
an
ubuntu
good
life

4

เรามีแพ็คเกจที่จะทำงานได้ดีมาก:

sudo apt-get install randomize-lines

ตัวอย่าง:

สร้างรายการหมายเลขที่เรียงลำดับแล้วบันทึกเป็น 1000.txt:

seq 1000 > 1000.txt

เพื่อสับเปลี่ยนเพียงใช้

rl 1000.txt

3

นี่เป็นสคริปต์หลามที่ฉันบันทึกเป็น rand.py ในโฟลเดอร์หน้าแรกของฉัน:

#!/bin/python

import sys
import random

if __name__ == '__main__':
  with open(sys.argv[1], 'r') as f:
    flist = f.readlines()
    random.shuffle(flist)

    for line in flist:
      print line.strip()

บน Mac OSX sort -Rและshufไม่สามารถใช้ได้ดังนั้นคุณสามารถใช้นามแฝงนี้ใน bash_profile ของคุณเป็น:

alias shuf='python rand.py'

3

ถ้าเช่นฉันคุณมาที่นี่เพื่อมองหาทางเลือกเพื่อshufสำหรับ MacOS randomize-linesแล้วการใช้งาน

ติดตั้งrandomize-lines(homebrew) แพคเกจซึ่งมีคำสั่งที่มีการทำงานคล้ายกับrlshuf

brew install randomize-lines

Usage: rl [OPTION]... [FILE]...
Randomize the lines of a file (or stdin).

  -c, --count=N  select N lines from the file
  -r, --reselect lines may be selected multiple times
  -o, --output=FILE
                 send output to file
  -d, --delimiter=DELIM
                 specify line delimiter (one character)
  -0, --null     set line delimiter to null character
                 (useful with find -print0)
  -n, --line-number
                 print line number with output lines
  -q, --quiet, --silent
                 do not output any errors or warnings
  -h, --help     display this help and exit
  -V, --version  output version information and exit

1
การติดตั้งกับ coreutils brew install coreutilsให้ไบนารีshuf gshuf
shadowtalker

2

หากคุณติดตั้ง Scala ไว้แล้วนี่เป็นหนึ่งซับเพื่อสับเปลี่ยนอินพุต:

ls -1 | scala -e 'for (l <- util.Random.shuffle(io.Source.stdin.getLines.toList)) println(l)'

เรียบง่าย แต่น่าดึงดูดใจเว้นแต่ว่า Java VM จะต้องเริ่มทำงานใหม่ราคาการเริ่มต้นนั้นมีจำนวนมาก ทำงานได้ไม่ดีนักเมื่อใช้จำนวนบรรทัดมาก
mklement0

1

ฟังก์ชัน bash นี้มีการพึ่งพาน้อยที่สุด (เรียงลำดับและทุบตีเท่านั้น):

shuf() {
while read -r x;do
    echo $RANDOM$'\x1f'$x
done | sort |
while IFS=$'\x1f' read -r x y;do
    echo $y
done
}

วิธีทุบตีที่ดีที่สอดคล้องกับวิธีแก้ปัญหาของตัวเองของ OP awkแต่ประสิทธิภาพจะเป็นปัญหากับอินพุตที่ใหญ่ขึ้น การใช้งานการ$RANDOMสลับค่าเดียวอย่างถูกต้องมีเพียงบรรทัดอินพุตสูงสุด 32,768 บรรทัดเท่านั้น ในขณะที่คุณสามารถขยายช่วงนั้นได้มันอาจจะไม่คุ้มค่าเช่นบนเครื่องของฉันการรันสคริปต์ของคุณใน 32,768 บรรทัดอินพุตสั้นใช้เวลาประมาณ 1 วินาทีซึ่งประมาณ 150 ครั้งตราบเท่าที่ใช้งาน shufและประมาณ 10-15 ครั้ง ตราบใดที่awkวิธีแก้ปัญหาของตัวเองช่วยOP ใช้ หากคุณสามารถพึ่งพาsortได้awkควรอยู่ที่นั่นเช่นกัน
mklement0

0

ใน windows คุณอาจลองชุดไฟล์นี้เพื่อช่วยให้คุณสลับ data.txt ของคุณการใช้งานของรหัสชุดคือ

C:\> type list.txt | shuffle.bat > maclist_temp.txt

หลังจากออกคำสั่งนี้ maclist_temp.txt จะมีรายการบรรทัดแบบสุ่ม

หวังว่านี่จะช่วยได้


ไม่ทำงานกับไฟล์ขนาดใหญ่ ฉันยอมแพ้หลังจาก 2 ชั่วโมงสำหรับไฟล์ 1 ล้านเส้น +
Stefan Haberl

0

ยังไม่ได้กล่าวถึง:

  1. การใช้unsortประโยชน์ ไวยากรณ์ (เป็นเพลย์ลิสต์ที่ค่อนข้างมุ่งเน้น):

    unsort [-hvrpncmMsz0l] [--help] [--version] [--random] [--heuristic]
           [--identity] [--filenames[=profile]] [--separator sep] [--concatenate] 
           [--merge] [--merge-random] [--seed integer] [--zero-terminated] [--null] 
           [--linefeed] [file ...]
  2. msort สามารถสุ่มได้ทีละบรรทัด แต่โดยทั่วไปแล้วจะเป็น overkill:

    seq 10 | msort -jq -b -l -n 1 -c r

0

awkตัวแปรอื่น:

#!/usr/bin/awk -f
# usage:
# awk -f randomize_lines.awk lines.txt
# usage after "chmod +x randomize_lines.awk":
# randomize_lines.awk lines.txt

BEGIN {
  FS = "\n";
  srand();
}

{
  lines[ rand()] = $0;
}

END {
  for( k in lines ){
    print lines[k];
  }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.