แยกไฟล์ทีละบรรทัดและควบคุมส่วนขยายของไฟล์ที่ได้


28

มีคำสั่งมาตรฐานสำหรับการแยกไฟล์ - แยก

ตัวอย่างเช่นหากฉันต้องการแยกไฟล์คำในหลาย ๆ บรรทัดของ 10,000 บรรทัดฉันสามารถใช้:

split -dl 10000 words wrd

และมันจะสร้างไฟล์หลายไฟล์ในรูปแบบ wrd.01, wrd.02 และอื่น ๆ

แต่ฉันต้องการมีส่วนขยายเฉพาะสำหรับไฟล์เหล่านั้น - ตัวอย่างเช่นฉันต้องการรับไฟล์ wtd.01.txt, wrd.02.txt

มีวิธีทำหรือไม่?

คำตอบ:


11

ไม่ใช่ด้วยsplitแต่คุณสามารถเปลี่ยนชื่อได้ในภายหลังหรือคุณสามารถทำได้ในawk:

awk '{filename = "wrd." int((NR-1)/10000) ".txt"; print >> filename}' inputfile

ดูดี - แต่ใช้งานไม่ได้ ในแบบฟอร์มของคุณบ่นเกี่ยวกับ "expression สำหรับ` >> 'การเปลี่ยนเส้นทางมีค่าสตริง null "และหาก" file "คือ" เปลี่ยน "เป็น" filename "เอาต์พุตไฟล์ของรูปแบบ wrd {หมายเลขไฟล์} {หมายเลขบรรทัด} .txt (ค่อนข้างเยอะ :)
Rogach

@Rogach ขออภัยฉันไม่ได้ทดสอบดังนั้นฉันลืม awk ไม่ทำการหารจำนวนเต็ม ฉันได้ทำการทดสอบอันนี้แล้ว
เควิน

49

ไม่สามารถใช้งานได้ในตอนนี้ แต่ด้วยเวอร์ชันล่าสุด ( ≥ 8.16) จำนวนgnu splitหนึ่งสามารถใช้--additional-suffixสวิตช์เพื่อควบคุมส่วนขยายที่เกิดขึ้น จากman split:

--additional-suffix=SUFFIX
              append an additional SUFFIX to file names.

ดังนั้นเมื่อใช้ตัวเลือกนั้น:

split -dl 10000 --additional-suffix=.txt words wrd

ชิ้นผลลัพธ์จะสิ้นสุดโดยอัตโนมัติใน.txt:

wrd00.txt
wrd01.txt
.........

3
ไม่ทำงานกับ mac
ericgu

2
ฉันรักการถากถางของคุณ ฉันเป็นยูนิกซ์ n00b จากโลกของ Apple ฉันใช้ OS X Yosemite และฉันไม่ต้องการให้คนอื่นชนและเผาแบบเดียวกับที่ฉันทำ ฉันทดสอบและตรวจทานที่เอกสารและเราไม่มีพารามิเตอร์นี้ ฉันอาจจะพลาดบางสิ่งบางอย่าง developer.apple.com/library/mac/documentation/Darwin/Reference/
......

5
@swiftshokunin - เกี่ยวข้องกับคำตอบของฉันเป็นส่วนหนึ่งของgnu split gnu coreutilsนอกจากนี้ยังมีให้ใน OSX หากคุณติดตั้งcoreutilsผ่านhomebrewแต่โปรดทราบว่าโดยค่าเริ่มต้นบน OSX gnuยูทิลิตี้จะมีgชื่อเป็นของพวกเขา (เช่นgstatแทนstat) ดังนั้นคุณจึงเรียกใช้มันเป็นgsplit(หรือเปลี่ยนเส้นทางตามคำแนะนำที่นี่หากคุณต้องการ เพื่อใช้เป็นsplitOSX split) HTH
don_crissti

1
คำตอบที่ดี บน OS X ให้ใช้gsplitเพื่อรับส่วนต่อท้ายที่เป็นตัวเลข (-d) เพื่อทำงาน
Brent Faust

1
ว้าวฉันไม่มีความคิดว่ามี gsplit - มันอาจมาจาก coreutils ที่กล่าวถึงข้างต้นและมันมี - ส่วนต่อท้ายเพิ่มเติม ขอขอบคุณทุกคนที่แสดงความคิดเห็นเกี่ยวกับวิธีแก้ปัญหานี้ :)
Łukasz Rysiak

13

งานดังกล่าวจัดการได้ดีที่สุดกับเชลล์ ใช้การแบ่งแล้วเขียนลูปง่าย ๆ เพื่อเปลี่ยนชื่อไฟล์ เช่น

for file in wrd.*
do
    mv "$file" "$file.txt"
done

จะเปลี่ยนชื่อไฟล์ wrd.01, wrd.02 ของคุณ ฯลฯ เพื่อให้ไฟล์เหล่านั้นมีนามสกุล. txt


ค่อนข้างชัดเจน แต่มันจะทำให้บทสรุปของ bash script กระชับ
Rogach

1
ปรัชญา Unix คือการมอบชุดเครื่องมือง่ายๆที่คุณรวมเข้าด้วยกันเพื่อทำงาน "ความกระชับของสคริปต์ทุบตี" ไม่ใช่ข้อกำหนดที่ระบุไว้ในคำถามของคุณ
Kyle Jones

7
PS: split+mvคำสั่งผสมนั้นเร็วกว่า6 เท่าawk (ประมาณ3 วินาทีกับ18 วินาที ) สำหรับไฟล์อินพุต 10 ล้านบรรทัด (75 MB) ... ข้อความในแต่ละบรรทัดเป็นหมายเลขบรรทัดของตัวเอง ... ขอบคุณสำหรับการระบุใหม่ "ชัดเจน" :)
Peter.O

3
PPS: ฉันเพิ่งจะตรวจสอบเรื่องนี้อีกเล็กน้อย ความเร็วที่แตกต่างนั้นเกี่ยวข้องกับจำนวนไฟล์ที่สร้างขึ้นเทียบกับจำนวนการจัดรูปแบบและการคำนวณทางคณิตศาสตร์ awk สำหรับแต่ละบรรทัดและทุกบรรทัดโดยไม่คำนึงถึงจำนวนไฟล์เอาต์พุต ... การใช้ไฟล์อินพุตเดียวกันกับตัวอย่างด้านบน: เมื่อมี100 ครั้งน้อยลงไฟล์split + mvเป็น75ครั้งเร็วกว่าawk: เมื่อมี100 ครั้งไฟล์split + mvเป็น1.5awkเท่าเร็วกว่า ดังนั้นสำหรับฉันsplit + mvวิธีนี้ชนะมือลง มันเป็น consice (เนื้อหา moreso) awkและจะเร็วกว่า
Peter.O

1
หากคุณกังวลว่ามันมีความยาว 5 บรรทัดให้ลองใช้วิธีนี้แทน: for file in wrd.*; do mv "$file" "$file.txt"; done:)
Tony
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.