बड़ी पाठ फ़ाइल को समान संख्या में लाइनों के साथ छोटी फ़ाइलों में कैसे विभाजित किया जाए?


514

मुझे एक बड़ी (लाइनों की संख्या से) सादा पाठ फ़ाइल मिली है जिसे मैं छोटी फ़ाइलों में विभाजित करना चाहता हूं, वह भी लाइनों की संख्या से। इसलिए अगर मेरी फ़ाइल में लगभग 2M लाइनें हैं, तो मैं इसे 10 फ़ाइलों में विभाजित करना चाहूंगा, जिसमें 200k लाइनें, या 100 फाइलें शामिल हैं जिसमें 20k लाइनें हैं (शेष के साथ एक फ़ाइल है; समान रूप से विभाज्य होने से कोई फर्क नहीं पड़ता)।

मैं इसे पायथन में काफी आसानी से कर सकता था, लेकिन मैं सोच रहा हूं कि अगर कोई बैश और यूनिक्स बर्तनों का उपयोग करने के लिए किसी भी तरह का निंजा तरीका है (जैसा कि मैन्युअल रूप से लूपिंग और काउंटिंग / विभाजन लाइनों के विपरीत)।


2
जिज्ञासा से बाहर, वे "विभाजित" होने के बाद, एक उन्हें "गठबंधन" कैसे करता है? "कैट पार्ट 2 >> पार्ट 1" जैसा कुछ? या वहाँ एक और निंजा उपयोगिता है? अपने सवाल को अपडेट करने का मन?
dlamotte

7
इसे वापस एक साथ रखने के लिए,cat part* > original
मार्क बायर्स

9
हाँ बिल्ली के बच्चे के लिए संक्षिप्त है। सामान्य एप्रोपोस में उपयुक्त कमांड खोजने के लिए उपयोगी है। IE का उत्पादन देखें:
एप्रोपोस

@pixelbeat जो बहुत अच्छा है, धन्यवाद
danben

3
एक तरफ के रूप में, OS X उपयोगकर्ताओं को यह सुनिश्चित करना चाहिए कि उनकी फ़ाइल में MAC OS X - स्टाइल एंड-ऑफ-लाइन संकेतक (CR) के बजाय LINUX या UNIX- शैली लाइन विराम / एंड-ऑफ़-लाइन संकेतक (LF) शामिल हैं - विभाजन और अगर आपके ब्रेक की तरह LineFeeds के बजाय Carage Returns हैं तो csplit कमांड काम नहीं करेंगे। अगर आप मैक ओएस पर हैं, तो बरबॉन्‍स सॉफ्टवेयर से टेक्स्टवंगलर इसमें आपकी मदद कर सकता है। आप चुन सकते हैं कि आप कैसे अपनी लाइन ब्रेक पात्रों को देखना चाहते हैं। जब आप अपनी पाठ फ़ाइलों को सहेजते हैं (या इस रूप में सहेजें ...)।

जवाबों:


855

क्या आपने विभाजन आदेश को देखा है?

$ split --help
Usage: split [OPTION] [INPUT [PREFIX]]
Output fixed-size pieces of INPUT to PREFIXaa, PREFIXab, ...; default
size is 1000 lines, and default PREFIX is `x'.  With no INPUT, or when INPUT
is -, read standard input.

Mandatory arguments to long options are mandatory for short options too.
  -a, --suffix-length=N   use suffixes of length N (default 2)
  -b, --bytes=SIZE        put SIZE bytes per output file
  -C, --line-bytes=SIZE   put at most SIZE bytes of lines per output file
  -d, --numeric-suffixes  use numeric suffixes instead of alphabetic
  -l, --lines=NUMBER      put NUMBER lines per output file
      --verbose           print a diagnostic to standard error just
                            before each output file is opened
      --help     display this help and exit
      --version  output version information and exit

आप ऐसा कुछ कर सकते हैं:

split -l 200000 filename

जो 200000 लाइनों के साथ प्रत्येक नाम की फाइलें बनाएगा xaa xab xac...

एक अन्य विकल्प, आउटपुट फ़ाइल के आकार से विभाजित (अभी भी लाइन ब्रेक पर विभाजन):

 split -C 20m --numeric-suffixes input_filename output_prefix

output_prefix01 output_prefix02 output_prefix03 ...अधिकतम आकार के 20 मेगाबाइट की तरह फाइलें बनाता है ।


16
आप एक फ़ाइल को आकार से विभाजित कर सकते हैं: split -b 200m filename(मेगाबाइट के लिए एम, किलोबाइट के लिए k या बाइट्स के लिए कोई प्रत्यय नहीं)
अभि बेकर्ट

136
आकार से विभाजित और सुनिश्चित करें कि फाइलें लाइन ब्रेक पर विभाजित हैं: विभाजन -C 200 मीटर फ़ाइल नाम
क्लेटन स्टेनली

2
स्प्लिट यूनिकोड (UTF-16) इनपुट के साथ गारबल्ड आउटपुट का उत्पादन करता है। कम से कम विंडोज पर मेरे पास संस्करण के साथ।
वर्टिगो

4
। मेरे पास ठीक वैसी ही समस्या थी जब तक कि मुझे सलाह का टुकड़ा नहीं मिला।
20

6
-dOSX पर विकल्प उपलब्ध नहीं है, gsplitइसके बजाय उपयोग करें । मैक उपयोगकर्ता के लिए यह उपयोगी उम्मीद है।
user5698801


39

हाँ, एक splitआज्ञा है। यह एक फाइल को लाइनों या बाइट्स से विभाजित करेगा।

$ split --help
Usage: split [OPTION]... [INPUT [PREFIX]]
Output fixed-size pieces of INPUT to PREFIXaa, PREFIXab, ...; default
size is 1000 lines, and default PREFIX is `x'.  With no INPUT, or when INPUT
is -, read standard input.

Mandatory arguments to long options are mandatory for short options too.
  -a, --suffix-length=N   use suffixes of length N (default 2)
  -b, --bytes=SIZE        put SIZE bytes per output file
  -C, --line-bytes=SIZE   put at most SIZE bytes of lines per output file
  -d, --numeric-suffixes  use numeric suffixes instead of alphabetic
  -l, --lines=NUMBER      put NUMBER lines per output file
      --verbose           print a diagnostic just before each
                            output file is opened
      --help     display this help and exit
      --version  output version information and exit

SIZE may have a multiplier suffix:
b 512, kB 1000, K 1024, MB 1000*1000, M 1024*1024,
GB 1000*1000*1000, G 1024*1024*1024, and so on for T, P, E, Z, Y.

Tried georgec @ ATGIS25 ~ $ स्प्लिट -l 100000 /cygdrive/P/2012/Job_044_DM_Radio_Propogation/Working/FinalPropogation/TRCongong/trc_longlands.txt लेकिन डायरेक्टरी-वे में कोई स्प्लिट फाइल्स नहीं हैं, आउटपुट है?
जॉर्ज मार्क

1
यह उसी निर्देशिका में होना चाहिए। उदाहरण के लिए अगर मैं फ़ाइल प्रति 1,000,000 लाइनों से विभाजित करना चाहते हैं, निम्न कार्य करें: split -l 1000000 train_file train_file.और एक ही निर्देशिका में मैं मिल जाएगा train_file.aaतो पहली मिलियन के साथ, trail_file.abअगले दस लाख, आदि के साथ
विल

1
@ जॉर्ज और आप उपसर्ग के साथ कस्टम आउटपुट निर्देशिका प्राप्त कर सकते हैं split input my/dir/:।
सिरो सेंटिल्ली :56 冠状 i i

15

उपयोग split

किसी फ़ाइल को निश्चित आकार के टुकड़ों में विभाजित करें, INPUT के लगातार वर्गों से युक्त आउटपुट फ़ाइलें बनाता है (यदि कोई इनपुट नहीं दिया गया है या INPUT `- 'है)

Syntax split [options] [INPUT [PREFIX]]

http://ss64.com/bash/split.html


13

उपयोग:

sed -n '1,100p' filename > output.txt

यहां 1 और 100 लाइन नंबर हैं, जिन्हें आप कैप्चर करेंगे output.txt


यह केवल पहले 100 लाइनों को प्राप्त करता है, आपको फ़ाइल को अगले 101..200 आदि में क्रमिक रूप से विभाजित करने के लिए इसे लूप करने की आवश्यकता है या बस splitपहले से बताए गए सभी शीर्ष उत्तरों की तरह इसका उपयोग करें।
ट्रिपल

10

फ़ाइल को "file.txt" को 10000 लाइनों की फाइलों में विभाजित करें:

split -l 10000 file.txt

9

split(GNU कोरुटिल्स से, 2010-12-22 के संस्करण 8.8 से ) में निम्न पैरामीटर शामिल हैं:

-n, --number=CHUNKS     generate CHUNKS output files; see explanation below

CHUNKS may be:
  N       split into N files based on size of input
  K/N     output Kth of N to stdout
  l/N     split into N files without splitting lines/records
  l/K/N   output Kth of N to stdout without splitting lines/records
  r/N     like 'l' but use round robin distribution
  r/K/N   likewise but only output Kth of N to stdout

इस प्रकार, बाइट्स की समान मात्रा के साथ split -n 4 input output.चार फाइलें ( output.a{a,b,c,d}) उत्पन्न होंगी , लेकिन लाइनें बीच में टूट सकती हैं।

यदि हम पूर्ण रेखाओं को संरक्षित करना चाहते हैं (अर्थात लाइनों द्वारा विभाजित), तो यह काम करना चाहिए:

split -n l/4 input output.

संबंधित उत्तर: https://stackoverflow.com/a/19031247


9

यदि आप बस प्रत्येक फ़ाइल की x संख्या रेखाओं से विभाजित करना चाहते हैं, तो दिए गए उत्तर splitठीक हैं। लेकिन, मुझे इस बात की उत्सुकता है कि आवश्यकताओं पर किसी ने ध्यान नहीं दिया:

  • "उन्हें गिनने के बिना" -> wc + कट का उपयोग कर
  • "अतिरिक्त फ़ाइल में शेष रहने" -> डिफ़ॉल्ट रूप से विभाजन करता है

मैं "wc + cut" के बिना ऐसा नहीं कर सकता, लेकिन मैं इसका उपयोग कर रहा हूं:

split -l  $(expr `wc $filename | cut -d ' ' -f3` / $chunks) $filename

यह आसानी से आपके bashrc कार्यों में जोड़ा जा सकता है ताकि आप इसे केवल फ़ाइल नाम और विखंडू पास करने के लिए आमंत्रित कर सकें:

 split -l  $(expr `wc $1 | cut -d ' ' -f3` / $2) $1

यदि आप अतिरिक्त फ़ाइल में शेष के बिना सिर्फ x चंक्स चाहते हैं, तो बस प्रत्येक फ़ाइल पर इसे (चंक्स - 1) को योग करने के सूत्र को अनुकूलित करें। मैं इस दृष्टिकोण का उपयोग करता हूं क्योंकि आम तौर पर मुझे प्रति फ़ाइल x लाइनों के बजाय केवल x संख्या की फाइलें चाहिए:

split -l  $(expr `wc $1 | cut -d ' ' -f3` / $2 + `expr $2 - 1`) $1

आप इसे एक स्क्रिप्ट में जोड़ सकते हैं और इसे अपना "निंजा तरीका" कह सकते हैं, क्योंकि अगर कुछ भी आपकी ज़रूरतों को पूरा नहीं करता है, तो आप इसे बना सकते हैं :-)


या, बस के -nविकल्प का उपयोग करें split
अमित नायडू


0

एचडीएफएस छोटी फ़ाइल प्राप्त करता है और संपत्ति के आकार में फैला होता है।

यह विधि लाइन ब्रेक का कारण बनेगी

split -b 125m compact.file -d -a 3 compact_prefix

मैं हर फाइल को लगभग 128MB में विभाजित और विभाजित करने की कोशिश करता हूं।

# split into 128m ,judge sizeunit is M or G ,please test before use.

begainsize=`hdfs dfs -du -s -h /externaldata/$table_name/$date/ | awk '{ print $1}' `
sizeunit=`hdfs dfs -du -s -h /externaldata/$table_name/$date/ | awk '{ print $2}' `
if [ $sizeunit = "G" ];then
    res=$(printf "%.f" `echo "scale=5;$begainsize*8 "|bc`)
else
    res=$(printf "%.f" `echo "scale=5;$begainsize/128 "|bc`)  # celling ref http://blog.csdn.net/naiveloafer/article/details/8783518
fi
echo $res
# split into $res files with number suffix.  ref  http://blog.csdn.net/microzone/article/details/52839598
compact_file_name=$compact_file"_"
echo "compact_file_name :"$compact_file_name
split -n l/$res $basedir/$compact_file -d -a 3 $basedir/${compact_file_name}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.