ด้วยfind
คุณซ้ำสามารถแสดงรายชื่อไฟล์ทั้งหมดที่ตรงกับเกณฑ์บางอย่างเช่นชื่อไฟล์
for file in $(find . -type f -name "*.csv"); do cat "$file" >> /path/to/output.csv; done
เมื่อเสร็จแล้วfind . -name "*.csv"
จะค้นหาไฟล์ CSV ทั้งหมดจากโฟลเดอร์ปัจจุบันที่คุณอยู่ ( .
) และลูปจะวนซ้ำในรายการนั้นต่อท้ายทุกสิ่งลงในoutput.csv
ไฟล์
แต่:ชื่อไฟล์ที่มีช่องว่าง, ตัวอักษรกลมและขึ้นบรรทัดใหม่อาจเป็นเรื่องยุ่งยากที่นี่ โซลูชันที่ปลอดภัยกว่าคือการใช้exec
สำหรับคำสั่ง find
find . -name "*.txt" -exec cat '{}' >> /path/to/output.csv ';'
ที่นี่'{}'
จะถูกแทนที่ด้วยค้นหาด้วยชื่อไฟล์ สำหรับ Q & A ยาวเกี่ยวกับสาเหตุที่นี้และวิธีการที่จะหลีกเลี่ยงปัญหาที่สามารถพบได้ที่นี่
ตอนนี้ถ้าคุณต้องการสร้างไฟล์ CSV หนึ่งไฟล์สำหรับแต่ละไดเรกทอรี - ขออภัยไม่เคยเห็นมาก่อน - ฉันอาจทำสิ่งนี้:
for dir in $(find . -type d); do find $dir -maxdepth 1 -name "*.csv" -exec cat {} >> "$dir/out" ';'; mv "$dir/out" "$dir/merged.csv"; done
แม้ว่าวิธีการแก้ปัญหาของ Franck ด้านล่างอาจมีประสิทธิภาพมากกว่า
ของหลักสูตรให้ความสนใจกับความแตกต่างระหว่างและ>
>>
อดีตจะตัดไฟล์ให้มีความยาวเป็นศูนย์เสมอก่อนที่จะเขียนลงไปในขณะที่ไฟล์หลังจะต่อท้ายไฟล์
เหตุผลที่ใช้cat *.csv > merged.csv
งานได้ - และทำไมในวงของคุณมันไม่ทำงาน - คือเชลล์จะขยายสัญลักษณ์แทนก่อนดังนั้นโดยทั่วไปจึงเห็น:
cat file1.csv file2.csv file3.csv > merged.csv
... ซึ่งแน่นอนว่าจะไม่เขียนทับอะไรเลย
$DIR
และ$dir
ไม่เหมือนกัน