ฉันจะแยกไฟล์ข้อความเป็น 70% และ 30% โดยใช้คำสั่ง split ได้อย่างไร
ฉันจะแยกไฟล์ข้อความเป็น 70% และ 30% โดยใช้คำสั่ง split ได้อย่างไร
คำตอบ:
คำสั่งด้านล่างจะทำงานสำหรับเปอร์เซ็นต์ที่สูงกว่า 50% (หากคุณต้องการแบ่งออกเป็นสองไฟล์เท่านั้น) วิธีที่รวดเร็วและสกปรก
1) แบ่ง 70% ตามบรรทัด
split -l $[ $(wc -l filename|cut -d" " -f1) * 70 / 100 ] filename
2) แยก 70% ตามจำนวนไบต์
split -b $[ $(wc -c filename|cut -d" " -f1) * 70 / 100 ] filename
split -l $[ $(wc -l filename | xargs | cut -d" " -f1) * 70 / 100 ] filename
คุณสามารถใช้csplit
เพื่อแบ่งออกเป็นสองส่วน (ใช้เปอร์เซ็นต์ใด ๆ ) เช่นชิ้นแรก - 20% แรกของบรรทัดชิ้นที่สอง - 80% ที่เหลือของบรรทัด:
csplit infile $(( $(wc -l < infile) * 2 / 10 + 1))
$(wc -l < infile)
: จำนวนบรรทัดทั้งหมด
2 / 10
: เปอร์เซ็นต์
+1
: เพิ่มหนึ่งบรรทัดเนื่องจากการcsplit
แยกup to but not including line N
คุณสามารถแยกได้ตามบรรทัดเท่านั้น
โดยพื้นฐานตราบใดที่คุณมีหมายเลขบรรทัดผ่าน$(( $(wc -l < file) * 2 / 10))
คุณสามารถใช้เครื่องมือที่มุ่งเน้นสายใด ๆ :
sed 1,$(( $(wc -l < infile) * 2 / 10))'{
w 20-infile
d
}' infile > 80-infile
หรือเย็นกว่า:
{ head -n$(( $(wc -l < infile) * 2 / 10)) > 20-infile; cat > 80-infile; } <infile
แม้ว่าบางคนhead
จะโง่และไม่ปฏิบัติตามมาตรฐานดังนั้นสิ่งนี้จะไม่ทำงานในการตั้งค่าทั้งหมด ...
{ BS=$(($(wc -c <file) * $P / 100))
dd count=1 bs="$BS" >file1; cat
} <file >file2 2>/dev/null
... ควรใช้กับกรณีง่าย ๆ นี้เพราะคุณแบ่งเพียงครั้งเดียว - และอาจsplit
เป็นเพราะ overkill เล็กน้อย ตราบใดที่ไฟล์เป็น seekable, dd
จะทำเพียงครั้งเดียวread()
บน<stdin
และอื่น ๆcat
ที่เหลืออยู่ที่จะเริ่มต้นของมันread()
ที่จุดใดdd
ใบมัน
ถ้าไฟล์มีขนาดใหญ่แล้ว count=1 bs=$big_ol_num
อาจได้รับความไม่สะดวกเล็กน้อยและสามารถบล็อกออกได้โดยใช้คณิตศาสตร์เชลล์พิเศษ
การป้อนข้อมูลที่ไม่ใช่ seekable - เช่นจากท่อ - อาจเอียงdd
's ผลแม้ว่าจะสามารถจัดการได้เป็นอย่างดี w / GNU dd
' iflag=fullblock
s
รหัสต่อไปนี้ใช้head
และtail
ทำงานร่วมกับอัตราส่วนใด ๆ (40 ถึง 60 ในกรณีนี้):
export FILE_NAME=train.vw
head -n $[ $(wc -l ${FILE_NAME}|cut -d" " -f1) * 40 / 100 ] ${FILE_NAME} > train_40.vw
tail -n +$[ ($(wc -l ${FILE_NAME}|cut -d" " -f1) * 40 / 100) + 1 ] ${FILE_NAME} > train_60.vw