2010-01-06 2 views
314

Tôi có một tệp văn bản thuần túy (theo số dòng) mà tôi muốn chia thành các tệp nhỏ hơn, cũng theo số dòng. Vì vậy, nếu tập tin của tôi có khoảng 2M dòng, tôi muốn chia nó thành 10 tập tin có chứa 200k dòng, hoặc 100 tập tin có chứa 20k dòng (cộng với một tập tin với phần còn lại; được chia đều không quan trọng).Cách tách một tệp văn bản lớn thành các tệp nhỏ hơn với số dòng bằng nhau?

Tôi có thể làm điều này khá dễ dàng bằng Python nhưng tôi tự hỏi liệu có cách nào để làm điều này bằng cách sử dụng bash và unix utils (trái với vòng lặp và đếm/phân vùng theo cách thủ công).

+1

Out of tò mò, sau khi họ đang "chia tay", làm thế nào để "kết hợp" họ? Một cái gì đó như "mèo part2 >> part1"? Hay là có một tiện ích ninja khác? nhớ cập nhật câu hỏi của bạn? – dlamotte

+3

Để đặt nó lại với nhau, 'cat part *> original' –

+6

có con mèo là viết tắt của concatenate. Nói chung apropos rất hữu ích cho việc tìm kiếm các lệnh thích hợp. I E. xem đầu ra của: apropos split – pixelbeat

Trả lời

543

Bạn đã xem lệnh chia tách chưa?

$ 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 

Bạn có thể làm một cái gì đó như thế này:

split -l 200000 filename 

mà sẽ tạo ra các file mỗi 200000 dòng tên xaa xab xac ...

Một tùy chọn khác, chia theo kích thước của tập tin đầu ra (vẫn còn chia rẽ trên ngắt dòng):

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

tạo tệp như output_prefix01 output_prefix02 output_prefix03 ... mỗi kích thước tối đa 20 megabyte.

+13

bạn cũng có thể chia nhỏ tệp theo kích thước: 'split -b 200m filename' (m cho megabyte, k đối với kilobyte hoặc không có hậu tố cho byte) –

+108

chia theo kích thước và đảm bảo các tệp được chia nhỏ trên ngắt dòng: phân tách -C 200m tên tệp –

+2

chia sẽ tạo ra kết quả bị cắt xén với đầu vào Unicode (UTF-16). Ít nhất là trên Windows với phiên bản tôi có. – Vertigo

10

sử dụng split

Chia một file thành miếng kích thước cố định, tạo ra tập tin đầu ra có chứa các phần liên tiếp của INPUT (đầu vào tiêu chuẩn nếu không được đưa ra hoặc đầu vào là `- ')

Syntax split [options] [INPUT [PREFIX]]

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

48

Làm thế nào về split lệnh?

split -l 200000 mybigfile.txt 
25

Có, có lệnh split. Nó sẽ chia nhỏ một tập tin theo dòng hoặc byte.

$ 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. 
+0

Đã thử bị gián đoạn @ ATGIS25 ~ $ split -l 100000 /cygdrive/P/2012/Job_044_DM_Radio_Propogation/Working/FinalPropogation/TRC_Longlands/trc_longlands.txt nhưng không có tệp tách trong thư mục ở đâu là đầu ra? – GeorgeC

+0

Nó phải nằm trong cùng một thư mục. Ví dụ. nếu tôi muốn chia cho 1.000.000 dòng cho mỗi tệp, hãy làm như sau: 'split -l 1000000 train_file train_file.' và trong cùng thư mục tôi sẽ nhận' train_file.aa' với triệu đầu tiên, sau đó 'trail_file.ab' với số triệu tiếp theo, v.v. – Will

+0

@GeorgeC và bạn có thể nhận các thư mục đầu ra tùy chỉnh với tiền tố: 'split input my/dir /'. –

6

bạn cũng có thể sử dụng awk

awk -vc=1 'NR%200000==0{++c}{print $0 > c".txt"}' largefile 
+0

Không tệ, nhưng không quá xa so với những gì tôi đã làm trong Python. – danben

+2

'awk -v lines = 200000 -v fmt ="% d.txt "'{print> sprintf (fmt, 1 + int ((NR-1)/dòng))}'' –

10

Sử dụng:

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

Ở đây, 1 và 100 là số dòng mà bạn sẽ chụp trong output.txt.

+1

Tôi thích câu trả lời này. Ngắn và ngọt. Cảm ơn – ChikuMiku

4

Trong trường hợp bạn chỉ muốn chia cho x số dòng mỗi tệp, số asnwers nhất định khoảng split là OK. Nhưng, tôi tò mò về không ai chú ý đến một số yêu cầu của người hỏi.

  • "whithout phải đếm chúng" -> sử dụng wc + cắt
  • "có thời gian còn lại trong tập tin thêm" -> chia làm theo mặc định

Tôi hiện đang sử dụng rằng:

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

này có thể dễ dàng thêm vào các chức năng bashrc của bạn vì vậy bạn chỉ có thể gọi nó đi qua tên tập tin và khối:

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

Trong trường hợp bạn chỉ muốn x khối không còn dư trong tệp phụ, chỉ cần điều chỉnh công thức để tính tổng nó (khối - 1) trên mỗi tệp. Tôi sử dụng phương pháp này vì thường tôi chỉ muốn x số lượng tệp thay vì x dòng cho mỗi tệp:

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

Bạn có thể thêm nó vào tập lệnh và gọi đó là "cách ninja" của bạn, bởi vì nếu không có bộ phần mềm nào bạn cần , bạn có thể xây dựng nó :-)

0

HDFS getmerge tệp nhỏ và tràn vào kích thước tài sản.

Phương pháp này sẽ gây ra ngắt dòng

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

tôi cố gắng getmerge và chia thành khoảng 128MB mỗi tập tin.

chia thành 128m, đánh giá sizeunit là M hoặc G, vui lòng kiểm tra trước khi sử dụng.

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} 
2

chia file "file.txt" vào 10000 dòng file:

split -l 10000 file.txt