ฉันจะสุ่มเส้นในไฟล์โดยใช้เครื่องมือมาตรฐานบน Red Hat Linux ได้อย่างไร
ฉันไม่มีshuf
คำสั่งดังนั้นฉันกำลังมองหาบางอย่างเช่น a perl
หรือawk
one-liner ที่ทำงานเดียวกันให้สำเร็จ
ฉันจะสุ่มเส้นในไฟล์โดยใช้เครื่องมือมาตรฐานบน Red Hat Linux ได้อย่างไร
ฉันไม่มีshuf
คำสั่งดังนั้นฉันกำลังมองหาบางอย่างเช่น a perl
หรือawk
one-liner ที่ทำงานเดียวกันให้สำเร็จ
คำตอบ:
และ Perl หนึ่งซับที่คุณจะได้รับ!
perl -MList::Util -e 'print List::Util::shuffle <>'
ใช้โมดูล แต่โมดูลเป็นส่วนหนึ่งของการแจกแจงรหัส Perl หากยังไม่ดีพอคุณอาจลองหมุนเอง
ฉันลองใช้สิ่งนี้กับ-i
แฟล็ก ("แก้ไขในสถานที่") เพื่อให้มันแก้ไขไฟล์ เอกสารแนะนำว่าควรใช้งานได้ แต่ไม่ได้ผล มันยังคงแสดงไฟล์ที่สับเป็น stdout แต่คราวนี้มันจะลบต้นฉบับ ฉันขอแนะนำให้คุณอย่าใช้มัน
พิจารณาเชลล์สคริปต์:
#!/bin/sh
if [[ $# -eq 0 ]]
then
echo "Usage: $0 [file ...]"
exit 1
fi
for i in "$@"
do
perl -MList::Util -e 'print List::Util::shuffle <>' $i > $i.new
if [[ `wc -c $i` -eq `wc -c $i.new` ]]
then
mv $i.new $i
else
echo "Error for file $i!"
fi
done
ยังไม่ทดสอบ แต่หวังว่าจะได้ผล
ruby -e 'puts STDIN.readlines.shuffle'
แต่มาข้ามเช่นทับทิมซึ่งมีประโยชน์ในการเป็นสั้น: จะต้องมีการทดสอบปัจจัยการผลิตขนาดใหญ่เพื่อดูว่าความเร็วเทียบได้หรือไม่ (ใช้งานได้กับ OS X ด้วย)
shuf
โหลดทุกอย่างลงในหน่วยความจำดังนั้นจึงใช้ไม่ได้กับไฟล์ขนาดใหญ่อย่างแท้จริง (ของฉันคือ ~ 300GB tsv) Perl สคริปต์นี้ล้มเหลวในเหมืองเกินไป Killed
แต่มีข้อผิดพลาดไม่มียกเว้น มีความคิดอย่างไรหากโซลูชัน perl กำลังโหลดทุกอย่างลงในหน่วยความจำด้วยหรือมีปัญหาอื่น ๆ ที่ฉันพบอยู่
อืมอย่าลืม
sort --random-sort
brew install coreutils
utils ทั้งหมดขึ้นต้นด้วย ag ดังนั้น: gsort --random-sort
หรือgshuf
จะทำงานตามที่คาดไว้
gsort
และgshuf
ติดตั้งเมื่อฉันทำport install coreutils
shuf
แทน (บน linux)
shuf
เป็นวิธีที่ดีที่สุด
sort -R
ช้าอย่างเจ็บปวด ฉันเพิ่งพยายามจัดเรียงไฟล์ 5GB ฉันยอมแพ้หลังจาก 2.5 ชั่วโมง จากนั้นshuf
จัดเรียงในหนึ่งนาที
sort -R
ช้าคือการคำนวณแฮชสำหรับแต่ละบรรทัด จากเอกสาร: " เรียงลำดับโดยการแฮชคีย์อินพุตจากนั้นเรียงลำดับค่าแฮช "
shuf
โหลดทุกอย่างในหน่วยความจำ
seq -f 'line %.0f' 1000000
เอาเดียวกันยาวเวลาในการประมวลผล (มากนานกว่าด้วยshuf
) ไม่ว่าหน่วยความจำมากฉันจัดสรร
cat yourfile.txt | while IFS= read -r f; do printf "%05d %s\n" "$RANDOM" "$f"; done | sort -n | cut -c7-
อ่านไฟล์นำหน้าทุกบรรทัดด้วยตัวเลขสุ่มเรียงไฟล์บนคำนำหน้าแบบสุ่มเหล่านั้นตัดคำนำหน้าหลังจากนั้น ซับเดียวซึ่งควรใช้กับเปลือกกึ่งโมเดิร์นใดก็ได้
แก้ไข: รวมคำพูดของ Richard Hansen
$RANDOM
) แต่ -1 สำหรับการฆ่าข้อมูล การแทนที่while read f
ด้วยwhile IFS= read -r f
จะป้องกันไม่ให้read
ลบช่องว่างนำหน้าและต่อท้าย (ดูคำตอบนี้ ) และป้องกันการประมวลผลแบ็กสแลช การใช้สตริงสุ่มที่มีความยาวคงที่จะป้องกันไม่ให้cut
ลบช่องว่างนำหน้า ผลลัพธ์: cat yourfile.txt | while IFS= read -r f; do printf "%05d %s\n" "$RANDOM" "$f"; done | sort -n | cut -c7-
หนึ่งซับสำหรับ python:
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)
เกี่ยวข้องกับคำตอบของ Jim:
ของฉัน~/.bashrc
ประกอบด้วยสิ่งต่อไปนี้:
unsort ()
{
LC_ALL=C sort -R "$@"
}
ด้วยการเรียงลำดับของ GNU coreutils -R
= --random-sort
ซึ่งสร้างแฮชแบบสุ่มของแต่ละบรรทัดและจัดเรียงตามมัน กัญชาแบบสุ่มจะไม่นำมาใช้จริงในสถานที่บางอย่างในบางรุ่นเก่า (รถ) LC_ALL=C
ทำให้มันกลับมาส่งออกเรียงตามปกติซึ่งเป็นเหตุผลที่ผมตั้ง
เกี่ยวข้องกับคำตอบของ Chris:
perl -MList::Util=shuffle -e'print shuffle<>'
เป็นซับเดียวที่สั้นกว่าเล็กน้อย ( -Mmodule=a,b,c
เป็นชวเลขสำหรับ-e 'use module qw(a b c);'
.)
เหตุผลที่ทำให้มันง่าย-i
ไม่ได้ผลสำหรับการสับในสถานที่เพราะ Perl คาดว่าสิ่งที่print
เกิดขึ้นในลูปเดียวกันกับไฟล์ที่กำลังอ่านอยู่และprint shuffle <>
จะไม่ส่งออกจนกว่าจะมีการอ่านและปิดไฟล์อินพุตทั้งหมด
วิธีแก้ปัญหาสั้น ๆ
perl -MList::Util=shuffle -i -ne'BEGIN{undef$/}print shuffle split/^/m'
จะสลับไฟล์ในสถานที่ ( -n
หมายถึง "ห่อรหัสในการwhile (<>) {...}
วนซ้ำBEGIN{undef$/}
ทำให้ Perl ดำเนินการกับไฟล์ทีละไฟล์แทนทีละบรรทัดและsplit/^/m
เป็นสิ่งที่จำเป็นเนื่องจาก$_=<>
ได้ทำโดยปริยายกับไฟล์ทั้งหมดแทนที่จะเป็นบรรทัด)
Mac OS X กับ DarwinPorts:
sudo port install unsort
cat $file | unsort | ...
FreeBSD มียูทิลิตี้แบบสุ่มของตัวเอง:
cat $file | random | ...
มันอยู่ใน / usr / games / random ดังนั้นหากคุณยังไม่ได้ติดตั้งเกมคุณจะโชคไม่ดี
คุณสามารถพิจารณาติดตั้งพอร์ตเช่น textproc / rand หรือ textproc / msort สิ่งเหล่านี้อาจพร้อมใช้งานบน Linux และ / หรือ Mac OS X หากเป็นปัญหาในการพกพา
บน OSX รับข้อมูลล่าสุดจากhttp://ftp.gnu.org/gnu/coreutils/และสิ่งที่ชอบ
./configure ทำให้ sudo ทำการติดตั้ง
... ควรให้คุณ / usr / local / bin / sort --random-sort
โดยไม่ทำให้สับสน / usr / bin / sort
หรือรับจาก MacPorts:
$ sudo port install coreutils
และ / หรือ
$ /opt/local//libexec/gnubin/sort --random-sort