ฉันมีไฟล์ CSV (ประมาณ 10,000 แถวแต่ละแถวมี 300 คอลัมน์) เก็บไว้ในเซิร์ฟเวอร์ LINUX ฉันต้องการแบ่งไฟล์ CSV นี้เป็นไฟล์ CSV 500 ไฟล์จาก 20 รายการต่อไฟล์ (แต่ละรายการมีส่วนหัว CSV เดียวกันกับที่มีอยู่ใน CSV เดิม)
มีคำสั่ง linux ช่วยการแปลงนี้หรือไม่
ฉันมีไฟล์ CSV (ประมาณ 10,000 แถวแต่ละแถวมี 300 คอลัมน์) เก็บไว้ในเซิร์ฟเวอร์ LINUX ฉันต้องการแบ่งไฟล์ CSV นี้เป็นไฟล์ CSV 500 ไฟล์จาก 20 รายการต่อไฟล์ (แต่ละรายการมีส่วนหัว CSV เดียวกันกับที่มีอยู่ใน CSV เดิม)
มีคำสั่ง linux ช่วยการแปลงนี้หรือไม่
คำตอบ:
เพื่อความสมบูรณ์นี่คือการปรับปรุงเล็กน้อย:
sed
ไม่มีไฟล์ชั่วคราว อย่างนี้:
header=$(head -n 1 file.csv)
tail -n +2 file.csv | split -l 20
for file in x??; do
sed -i -e 1i$'\\\n'"$header" "$file"
done
$'\\\n'
มีอักขระขึ้นบรรทัดใหม่ด้วยเครื่องหมายแบ็กสแลช sed
expression หมายถึง: ใส่ $header
ก่อนบรรทัดที่ 1
สิ่งนี้ควรทำ ไม่มี ส่วนหัวของ CSV:
tail -n +2 file.csv | split -l 20
จากนั้นคุณสามารถเพิ่มส่วนหัวในแต่ละไฟล์:
for file in x*
do
(head -n 1 file.csv; cat "$file") > "$file".new
mv "$file".new "$file" # Stolen from @PawanMude's answer
done
ลอง:
fn="infile" c=0
{
read header
split -a 3 -l 3 - "$fn"
for f in "$fn"???; do
c=$((c+1))
printf "%s\n" "$header" | cat - "$f" > "${f%???}-$c" && rm "$f"
done
} < $fn
หรือลองด้วย awk:
awk 'NR==1{h=$0; next} !((NR-2)%n){close(f); f=FILENAME "-" ++c; print h>f}{print>f}' n=3 infile
รุ่นหลายสาย:
awk '
NR==1 {
h=$0
next
}
!((NR-2)%n) {
close(f)
f=FILENAME "-" ++c
print h>f
}
{
print>f
}
' n=3 infile
วิธีที่ดีที่สุดในการแก้ปัญหานี้โดยใช้ POST ที่กล่าวถึงด้านล่าง:
tail -n +2 file.txt | split -l 4 - split_
for file in split_*
do
head -n 1 file.txt > tmp_file
cat $file >> tmp_file
mv -f tmp_file $file
done
ใช้ GNU Parallel:
cat bigfile.csv | parallel -N20 --header : --pipe 'cat > {#}'
หากคุณต้องการเรียกใช้คำสั่งในแต่ละส่วน GNU Parallel ก็สามารถช่วยได้เช่นกัน:
cat bigfile.csv | parallel -N20 --header : --pipe my_program_reading_from_stdin
cat bigfile.csv | parallel -N20 --header : --pipe --cat my_program_reading_from_a_file {}