큰 텍스트 파일을 같은 줄 수의 작은 파일로 나누는 방법은 무엇입니까?


515

큰 줄 수의 일반 텍스트 파일을 가지고 있으며 작은 줄로 나눠서 작은 파일로 나눕니다. 따라서 파일에 약 2M 줄이 있으면 200k 줄이 포함 된 10 개의 파일 또는 20k 줄이 포함 된 100 개의 파일로 분할하고 싶습니다 (나머지가있는 하나의 파일; 고르게 나눌 수는 중요하지 않음).

파이썬에서 상당히 쉽게 할 수 있지만 bash와 유닉스 유틸리티를 사용하여 닌자 방법이 있는지 궁금합니다 (수동으로 루핑하고 계산 / 분할하는 것이 아니라).


2
호기심에서, 그들이 "분할"된 후에, 어떻게 그들은 "결합"합니까? "고양이 part2 >> part1"과 같은 것? 아니면 다른 닌자 유틸리티가 있습니까? 질문을 업데이트 하시겠습니까?
dlamotte

7
다시 정리하자면cat part* > original
Mark Byers

9
그렇습니다 고양이는 연결하기에 짧습니다. 일반적으로 apropos는 적절한 명령을 찾는 데 유용합니다. IE는 다음의 결과를 봅니다 : apropos split
pixelbeat

@pixelbeat 감사합니다
danben

3
또한, OS X 사용자는 파일에 MAC OS X 대신 LINUX 또는 UNIX 스타일 줄 바꿈 / 줄 끝 표시기 (LF)가 포함되어 있는지 확인해야합니다. csplit 명령은 like break가 LineFeeds 대신 Carriage Return 인 경우 작동하지 않습니다. Mac OS를 사용하는 경우 BareBones 소프트웨어의 TextWrangler가이를 지원합니다. 줄 바꿈 문자의 모양을 선택할 수 있습니다. 텍스트 파일을 저장할 때 (또는 다른 이름으로 저장 ...)

답변:


856

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 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 ...최대 크기가 각각 20MB 인 파일을 만듭니다 .


16
: 당신은 또한 크기로 파일을 분할 할 수 있습니다 split -b 200m filename(메가 바이트 m을 킬로바이트 또는 바이트없는 접미사 K)
Abhi 베커

136
크기별로 분할 및 확인 파일은 줄 바꿈에 분할 : 분할 -C의 200m 파일 이름
클레이튼 스탠리

2
split은 유니 코드 (UTF-16) 입력으로 잘못된 출력을 생성합니다. 최소한 내가 가지고있는 버전의 Windows에서는.
Vertigo

4
@geotheory, TextWrangler 또는 BBEdit를 사용하여 CR (Mac) 줄 끝을 LR (Linux) 줄 끝으로 먼저 변환하는 방법에 대해서는 스레드 앞부분의 LeberMac의 조언을 따르십시오. 그 조언을 찾을 때까지 나는 당신과 똑같은 문제를 겪었습니다.
sstringer

6
-dOSX에서는 옵션을 사용할 수 없습니다 gsplit. 대신 사용하십시오. Mac 사용자에게 유용한 정보가 되길 바랍니다.
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.

시도 georgec @ ATGIS25 ~ $ split -l 100000 /cygdrive/P/2012/Job_044_DM_Radio_Propogation/Working/FinalPropogation/TRC_Longlands/trc_longlands.txt 그러나 디렉토리에 분할 파일이 없습니다-출력은 어디에 있습니까?
GeorgeC

1
동일한 디렉토리에 있어야합니다. 예를 들어 파일 당 1,000,000 줄로 나누려면 다음을 수행하십시오. split -l 1000000 train_file train_file.같은 디렉토리 train_file.aa에서 첫 번째 백만 trail_file.ab
Will

1
@GeorgeC 및 접두사를 사용하여 사용자 정의 출력 디렉토리를 얻을 수 있습니다 split input my/dir/.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

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이미 여기에 나와있는 모든 최상위 답변처럼 사용 하십시오.
tripleee '

10

"file.txt"파일을 10000 라인 파일로 분할하십시오.

split -l 10000 file.txt

9

split(GNU coreutils, 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 + cut 사용
  • "추가 파일에 나머지가있는"-> 기본적으로 split

"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.
Amit Naidu

8

당신은 또한 awk를 사용할 수 있습니다

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

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

0

HDFS는 작은 파일을 가져오고 속성 크기에 쏟았습니다.

이 방법은 줄 바꿈을 일으킬 것입니다

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

getmerge를 시도하고 파일마다 약 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}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.