bash 쉘스크립트 - 대형 텍스트 파일을 동일한 수의 줄이있는 더 작은 파일로 분할하는 방법?




사용법 예제 (9)

split 사용

파일을 고정 크기로 분할하고, INPUT의 연속 섹션을 포함하는 출력 파일을 만듭니다 (지정되지 않은 경우 표준 입력 또는 INPUT이 '-'임).

Syntax split [options] [INPUT [PREFIX]]

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

큰 파일 (줄 수에 따라)을 일반 텍스트 파일로 만들어 작은 파일로 나눌 수도 있고 줄 수로 나눌 수도 있습니다. 따라서 내 파일의 길이가 2M 줄 정도라면 200k 줄을 포함하는 10 개의 파일 또는 20k 줄을 포함하는 100 개의 파일 (나머지 파일과 함께 하나의 파일, 균등하게 나눌 수 있다는 것은 중요하지 않음)로 나누고 싶습니다.

나는 이것을 파이썬에서 상당히 쉽게 할 수 있었지만 bash와 유닉스 utils를 사용하여 이것을 수행하는 닌자 방법이 있는지 궁금하다. (수동 루핑과 카운팅 / 파티션 분할과는 대조적이다.)


단지 각 파일 x 줄의 수로 나누고 싶을 때, 분할에 관한 주어진 질문은 괜찮습니다. 그러나 아무도 요구 사항에주의를 기울이지 않는다는 것이 궁금합니다.

  • "whithout은 그들을 계산해야합니다"-> 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

이 스크립트를 스크립트에 추가하고 "ninja way"라고 부를 수 있습니다. 왜냐하면 아무 것도 사용자의 필요에 맞지 않으면 빌드 할 수 있기 때문입니다 :-)


용도:

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

여기에서 1과 100은 output.txt 캡처 할 줄 번호입니다.


"file.txt"파일을 10000 줄로 나눕니다. files :

split -l 10000 file.txt

split 명령은 어때?

split -l 200000 mybigfile.txt

awk도 사용할 수 있습니다.

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

분할 명령을 보셨습니까?

$ 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

xaa xab xac 라는 이름의 200000 개의 라인이있는 파일을 생성합니다.

또 다른 옵션은 출력 파일의 크기별로 나눕니다 (여전히 줄 바꿈을 통해 분할됩니다).

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

output_prefix01 output_prefix02 output_prefix03 ... 최대 크기 20 메가 바이트와 같은 파일을 생성합니다.


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

이 방법은 줄 바꿈을 유발합니다.

분할 -b 125m compact.file -d -a 3 compact_prefix

나는 약화하려고하고 모든 파일에 대해 약 128MB로 나눕니다.

128m로 나누고, 판사는 M 또는 G, 사용 전에 테스트하십시오.

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}

당신은 이것을 시도 할 수 있습니다 (더 안전한) :

try:
    # http://effbot.org/zone/python-with-statement.htm
    # 'with' is safer to open a file
    with open('whatever.txt') as fh:
        # Do something with 'fh'
except IOError as e:
    print("({})".format(e))

출력은 다음과 같습니다.

([Errno 2] 해당 파일이나 디렉토리가 없습니다 : 'whatever.txt')

그런 다음 결과에 따라 프로그램을 계속 실행하거나 원하는 경우 코드를 중지 할 수 있습니다.





bash file unix