การเชื่อมต่อไฟล์และแทรกบรรทัดใหม่ระหว่างไฟล์


127

ฉันมีหลายไฟล์ที่ฉันต้องการที่จะ concat catกับ เอาเป็นว่า

File1.txt 
foo

File2.txt
bar

File3.txt
qux

ฉันต้องการเชื่อมต่อเพื่อให้ไฟล์สุดท้ายมีลักษณะดังนี้:

foo

bar

qux

แทนที่จะเป็นแบบนี้ด้วย cat File*.txt > finalfile.txt

foo
bar 
qux

วิธีที่ถูกต้องคืออะไร?


คำตอบ:


121

คุณทำได้:

for f in *.txt; do (cat "${f}"; echo) >> finalfile.txt; done

ตรวจสอบให้แน่ใจว่าfinalfile.txtไม่มีไฟล์ก่อนที่คุณจะรันคำสั่งด้านบน

หากคุณได้รับอนุญาตให้ใช้awkคุณสามารถทำได้:

awk 'FNR==1{print ""}1' *.txt > finalfile.txt

10
AWK '{print $0}' *.txt
จับเวลา

7
สิ่งนี้มีข้อบกพร่องที่ชัดเจนคือจะมีบรรทัดว่างที่ส่วนท้าย (จากทางเลือกแรก) หรือในตอนต้น (ทางเลือกที่สอง) คุณสามารถป้องกันสิ่งนี้awk 'FNR==1 && NR > 1 ...'แทนได้อย่างง่ายดาย
tripleee

5
หากคุณใส่>finalfile.txtหลังdoneคุณสามารถเขียนทับแทนการผนวกซึ่งจะลบข้อกำหนดเพื่อให้แน่ใจว่าไฟล์หายไปหรือว่างเปล่าก่อนการวนซ้ำ
tripleee

53

หากคุณมีไฟล์ไม่มากพอที่จะแสดงรายการแต่ละไฟล์คุณสามารถใช้การแทนที่กระบวนการใน Bash โดยการแทรกขึ้นบรรทัดใหม่ระหว่างไฟล์แต่ละคู่:

cat File1.txt <(echo) File2.txt <(echo) File3.txt > finalfile.txt

1
สวย! ขอบคุณ
Bob Kocisko

สิ่งนี้ใช้ได้ดีสำหรับฉันสำหรับใบรับรอง Letsencrypt ของฉันในการสร้างไฟล์. pem
leeman24

35

ถ้าเป็นฉันฉันจะใช้ sed:

sed -e '$s/$/\n/' -s *.txt > finalfile.txt

ในรูปแบบ sed นี้ $ มีสองความหมายประการแรกตรงกับหมายเลขบรรทัดสุดท้ายเท่านั้น (เป็นช่วงของบรรทัดที่จะใช้รูปแบบ) และประการที่สองจะจับคู่กับจุดสิ้นสุดของบรรทัดในรูปแบบการแทนที่

หากเวอร์ชัน sed ของคุณไม่มี-s(ประมวลผลไฟล์อินพุตแยกต่างหาก) คุณสามารถทำทุกอย่างแบบวนซ้ำได้:

for f in *.txt ; do sed -e '$s/$/\n/' $f ; done > finalfile.txt

3
หรือใน GNU sed:sed -s '$G' *.txt > finalfile.txt
Ruud Helderman

กระแสเดียว! นี่ควรเป็นคำตอบที่ได้รับการยอมรับ!
Yassine ElBadaoui

ระวังพวกฉันเพิ่งพังพีซีของฉันเพราะฉันใช้findแทน*.txtซึ่งหมายความว่าไฟล์นั้นถูกผนวกเข้ากับตัวมันเอง!
Xerus

11

คุณสามารถทำได้โดยใช้xargsถ้าคุณต้องการ แต่แนวคิดหลักยังคงเหมือนเดิม:

find *.txt | xargs -I{} sh -c "cat {}; echo ''" > finalfile.txt

1
ขอบคุณ ฉันพบว่าxargsใช้งานง่ายกว่าลูปในแบชมาก
RawwrBag

9

สิ่งนี้ใช้ได้ใน Bash:

for f in *.txt; do cat $f; echo; done

ตรงกันข้ามกับคำตอบด้วย>>(ผนวก) ผลลัพธ์ของคำสั่งนี้สามารถถูกส่งไปยังโปรแกรมอื่นได้

ตัวอย่าง:

  • for f in File*.txt; do cat $f; echo; done > finalfile.txt
  • (for ... done) > finalfile.txt (parens เป็นทางเลือก)
  • for ... done | less (ท่อน้อยลง)
  • for ... done | head -n -1 (สิ่งนี้ตัดออกจากเส้นว่างที่ต่อท้าย)

7

นั่นเป็นวิธีที่ฉันเพิ่งทำบน OsX 10.10.3

for f in *.txt; do (cat $f; echo '') >> fullData.txt; done

เนื่องจากคำสั่ง 'echo' ที่เรียบง่ายโดยไม่มีพารามิเตอร์สิ้นสุดลงโดยไม่มีการแทรกบรรทัดใหม่


สิ่งนี้ทำให้สตริงที่ส่วนท้ายของไฟล์ ฉันจะแทรกระหว่างแต่ละไฟล์ได้อย่างไร
onassar

3

ใน python สิ่งนี้จะเชื่อมต่อกับบรรทัดว่างระหว่างไฟล์ ( ,ระงับการเพิ่มบรรทัดว่างต่อท้าย):

print '\n'.join(open(f).read() for f in filenames),

นี่คือ python one-liner ที่น่าเกลียดซึ่งสามารถเรียกได้จากเชลล์และพิมพ์เอาต์พุตไปยังไฟล์:

python -c "from sys import argv; print '\n'.join(open(f).read() for f in argv[1:])," File*.txt > finalfile.txt
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.