निर्दिष्ट पंक्तियों की संख्या के अनुसार CSV फ़ाइलों को कैसे विभाजित करें?


84

मेरे पास CSV फ़ाइल है (लगभग 10,000 पंक्तियाँ; प्रत्येक पंक्ति में 300 कॉलम हैं) LINUX सर्वर पर संग्रहीत हैं। मैं इस CSV फ़ाइल को 20 रिकॉर्ड की 500 CSV फ़ाइलों में से प्रत्येक में तोड़ना चाहता हूं। (मूल CSV में मौजूद प्रत्येक CSV हेडर के समान)

क्या इस रूपांतरण में मदद करने के लिए कोई लिनक्स कमांड है?


1
यह वास्तव में काम करता है, हालांकि, पहली फ़ाइल के हेडर को डुप्लिकेट किया जाएगा इस प्रकार पहली सीएसवी फ़ाइल 2 हेडर दी जाएगी।
रिकमैन


जवाबों:


79

इसे फंक्शन में बनाया। अब आप कॉल कर सकते हैंsplitCsv <Filename> [chunkSize]

splitCsv() {
    HEADER=$(head -1 $1)
    if [ -n "$2" ]; then
        CHUNK=$2
    else 
        CHUNK=1000
    fi
    tail -n +2 $1 | split -l $CHUNK - $1_split_
    for i in $1_split_*; do
        sed -i -e "1i$HEADER" "$i"
    done
}

इस पर मिला: http://edmondscommerce.github.io/linux/linux-split-file-eg-csv-and-keep-header-row.html


1
क्या आप इसके काम करने के तरीके को समझा सकते हैं? मैंने मूल पोस्ट की जाँच की लेकिन कोई स्पष्टीकरण नहीं है, और टिप्पणी पोस्ट करने का विकल्प भी नहीं है।
शशि009

6
क्या होगा यदि CSV में एक सेल में एक नई रेखा होती है?
ओन्देजे ह्लावेक

यह किस तरह का न्यूलाइन कैरेक्टर है? यह अभी भी मेरे लिए काम करता है, UTF-8 पर, सुनिश्चित नहीं है कि यह मदद करता है।
उल्लू का पट्ठा

3
@ shashi009: मान लें कि मूल फ़ाइल को file.txt कहा जाता है। 1: पहली लाइन को छोड़ें, फिर बाकी फाइल को पाइप करें split, जो प्रत्येक 20 लाइनों में लंबी नई फाइलों में विभाजित हो, उपसर्ग split_2 के साथ: नई स्प्लिट_ * फाइलों के माध्यम से, प्रत्येक नाम को वेरिएबल में स्टोर करके file, एक बार में एक 3: प्रत्येक के लिए ... 4: पहली पंक्ति (कॉलम हेडर) को हमारी मूल फ़ाइल से tmp_file 5 तक लिखें : 20 लाइन विभाजन फ़ाइल को tmp_file 6 में जोड़ें: पुरानी विभाजन_ * फ़ाइल को नए के साथ अधिलेखित करें tmp_file, इसलिए यह कॉलम हेडर रखता है।
डेविड

1
हेडर के माध्यम से बहाना echo -e "$HEADER\n$(cat $i)" > $iअनावश्यक रूप से अपूर्ण है । मैंने इसे बदल दिया sed -i -e "1i$HEADER" "$i"
फिलिप मोर्स

149

लिनक्स स्प्लिट कमांड का उपयोग करें:

split -l 20 file.txt new    

फ़ाइल "file.txt" को "नई" नाम से शुरू होने वाली फ़ाइलों में विभाजित करें, प्रत्येक में प्रत्येक पाठ की 20 पंक्तियाँ हों।

man splitअधिक जानकारी के लिए यूनिक्स प्रॉम्प्ट पर टाइप करें। हालाँकि आपको पहले शीर्षलेख को file.txt ( tailउदाहरण के लिए कमांड का उपयोग करके) से निकालना होगा , और फिर इसे विभाजित फ़ाइलों में से प्रत्येक पर वापस जोड़ना होगा।


मैं फ़ाइल को कैसे छोड़ सकता हूँ।
forkfork

wc -lलाइनों की संख्या प्राप्त करने के लिए उपयोग करें, फिर इस मान को घटाएं 1 (मान लीजिए कि wc -l50 दिया) और फिर tail -n 49हेडर लाइन को छोड़कर सब कुछ प्राप्त करने के लिए (इस उदाहरण में) चलाएं । ध्यान दें कि wc -l<newline> वर्णों को गिना जाता है, इसलिए यदि अंतिम पंक्ति किसी newline वर्ण में समाप्त नहीं होती है तो आप अपनी लाइनों की संख्या में 1 से दूर हो जाएंगे।
लुकास रॉबर्ट्स

4
@ लुकास, tail -n +2 सभी लाइनों को प्रिंट करेगा लेकिन पहला
जेम्स किंग

@JamesKing, +1 और धन्यवाद! मुझे डॉक्स को अधिक बारीकी से पढ़ना चाहिए :)
लुकास रॉबर्ट्स

6
नई फाइलों में ".csv" रखने के लिए बस--additional-suffix=.csv
Cocuba

22

यह काम करना चाहिए !!!

file_name= उस फ़ाइल का नाम जिसे आप विभाजित करना चाहते हैं।
10000= प्रत्येक विभाजन फ़ाइल की पंक्तियों की संख्या में
file_part_= विभाजित फ़ाइल नाम का उपसर्ग होगा (file_part_0, file_part_1, file_part_2..etc आगे बढ़ता है)

विभाजन -d -l 10000 file_name.csv file_part_


यह बिल्कुल ठीक काम करता है! क्या कोई तरीका है जिससे मैं 10000 पंक्ति फ़ाइलों की संख्या को सीमित कर सकता हूं जो मैं बनाता हूं। मान लें कि मैं पहली 200,000 पंक्तियों को 10k पंक्ति सीएसवी फाइलों में विभाजित करना चाहता हूं और बाकी को अनदेखा करता हूं।
प्रोनोमिता डे

1
@Pronomitahead -200000 file.csv | split -l 10000 - new_
boloyao

2
मेरे पास एक भ्रष्ट लाइन के साथ एक 13 Gb CSV फ़ाइल थी ~ 69 000 000 के बारे में लाइन में। यह आयात को बड़े पैमाने पर रोक रहा था। जब तक मैं रेखा को अलग नहीं कर सकता और इसे ठीक कर सकता हूं, तब तक मुझे इसे पुन: विभाजित करने की अनुमति दी गई। कोई अन्य समाधान सर्वर को नीचे लाने या चीजों को लॉक किए बिना बड़ी फ़ाइलों को संभालने में उतना कुशल नहीं था। 5 000 000 पंक्ति विखंडू में फ़ाइल को विभाजित करने के लिए लगभग 2 मिनट का समय लगा। धन्यवाद!
एलपी

13

यह आपके लिए करना चाहिए - आपकी सभी फाइलें Part1-Part500 नामक समाप्त हो जाएंगी।

#!/bin/bash
FILENAME=10000.csv
HDR=$(head -1 $FILENAME)   # Pick up CSV header line to apply to each file
split -l 20 $FILENAME xyz  # Split the file into chunks of 20 lines each
n=1
for f in xyz*              # Go through all newly created chunks
do
   echo $HDR > Part${n}    # Write out header to new file called "Part(n)"
   cat $f >> Part${n}      # Add in the 20 lines from the "split" command
   rm $f                   # Remove temporary file
   ((n++))                 # Increment name of output part
done

इसने फाइलें
बनाईं

यह संख्याओं को पैडिंग करके थोड़ा सुधारा जा सकता है ताकि फाइलें लगातार अपने आप प्रदर्शित हों। $ {N} को $ (प्रिंटफ "% 05d \ n" $ n) से बदलकर
फिनीस डेशेव्स्की

4
पहली फ़ाइल में हैडर लाइन को डुप्लिकेट किया गया है।
जूहा पालोम्की

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.