키워드 경계를 사용하여 파일을 분할하는 방법

키워드 경계를 사용하여 파일을 분할하는 방법

많은 vcard가 포함된 vcf 파일이 있습니다.

vcf 파일을 Outlook으로 가져올 때 첫 번째 vcard만 가져온 것 같습니다.

그래서 나는 그들을 분리하고 싶다.

vcard가 다음으로 시작한다는 점을 고려하면

BEGIN:VCARD

그리고

END:VCARD

각 vcard를 자체 파일로 분할하는 가장 좋은 방법은 무엇입니까?

감사해요

고쳐 쓰다

귀하의 모든 응답에 감사드립니다. 이러한 성격의 질문과 마찬가지로 고양이의 가죽을 벗기는 방법에는 여러 가지가 있습니다. 그래서 이것을 선택했습니다.

모으다

다음은 각 답변에서 내가 좋아하는 점과 다른 답변 중 하나를 선택하게 된 이유에 대한 요약입니다.

  • csplit: 저는 이 접근 방식의 단순함이 정말 마음에 듭니다. 파일 확장자도 설정할 수 있었으면 좋겠습니다.
  • gawk: 내가 요청한 모든 작업을 수행합니다.
  • paralell: 일했다. 하지만 새로운 것을 설치해야 해요. (또한 내 홈 디렉토리에 새로운 /bin 디렉토리를 만들기로 결정했습니다)
  • perl:연락처 이름을 기반으로 vcf를 생성하는 것이 마음에 듭니다. 하지만 -o 옵션은 실제로 작동하지 않습니다.

결론적으로

  • 그래서 가장 먼저 떠난 것은 perl조금 낡아서였다.
  • 다음은 paralell뭔가 새로 설치해야 해서
  • 다음은 csplit내가 아는 한 출력 파일에 확장자를 생성할 수 없기 때문 입니다.
  • 즉시 사용할 수 있는 유틸리티이고 파일 이름을 약간 수정할 수 있을 만큼 다재다능하기 때문에 상은 멍청이에게 돌아갑니다. 추가 포인트도 있어요 cmp:)

답변1

awk를 사용하여 이 작업을 수행할 수 있습니다.

$ curl -O https://raw.githubusercontent.com/qtproject/qt-mobility\
/d7f10927176b8c3603efaaceb721b00af5e8605b/demos/qmlcontacts/contents/\
example.vcf

$ gawk ' /BEGIN:VCARD/ { close(fn); ++a; fn=sprintf("card_%02d.vcf", a); 
        print "Writing: ", fn } { print $0 > fn; } ' example.vcf
Writing:  card_01.vcf
Writing:  card_02.vcf
Writing:  card_03.vcf
Writing:  card_04.vcf
Writing:  card_05.vcf
Writing:  card_06.vcf
Writing:  card_07.vcf
Writing:  card_08.vcf
Writing:  card_09.vcf

$ cat card_0* > all.vcf
$ cmp example.vcf all.vcf
$ echo $?
0

세부 사항

awk 라인은 다음과 같이 작동합니다. a이는 각 라인마다 증가하는 카운터이고 BEGIN:VCARD, sprintf는 출력 파일 이름(에 저장됨 fn)을 구성하는 데 사용됩니다. 각 줄에 대해 현재 줄( $0)이 현재 파일( 이름 fn)에 추가됩니다.

최종 echo $?표시는 cmp성공입니다. 즉, 연결된 모든 개별 파일이 원본 샘플 vcf 샘플과 동일합니다.

awk의 출력 리디렉션은 셸의 출력 리디렉션과 다릅니다. 이는 > fnawk가 먼저 파일이 이미 열려 있는지 확인한다는 것을 의미합니다. 이미 열려 있으면 awk그것에 덧붙이다. 그렇지 않은 경우에는 열리고 잘립니다.

이러한 리디렉션 논리로 인해 우리는명시적으로 닫아야 합니다.암시적으로 열리는 파일. 그렇지 않으면 입력 파일에 많은 레코드가 포함된 경우 호출이 파일 열기 제한에 도달하게 됩니다.

답변2

csplit -f vcard input.txt -z '/END:VCARD/+1' '{*}'

답변3

csplit의 Gnu 버전은 확장자를 설정할 수 있습니다. Ignacio의 대답은 제 생각에는 가장 깔끔합니다. 확장자를 얻으려면 "printf" 형식을 사용하여 마지막으로 한 번만 조정하면 됩니다.

csplit -f vcard -b %02d.vcard input.txt -z '/END:VCARD/+1' '{*}'

다음은 GNU 매뉴얼 페이지의 관련 스니펫입니다 csplit.

   -b, --suffix-format=FORMAT
          use sprintf FORMAT instead of %02d

답변4

이 스크립트를 사용하여 작업을 수행할 수 있습니다. 그것은 알려져있다vcf 파일 분할.

사용 예

$ split_vcf.pl 

Error! Input VCF filename missing,  -i

Usage: perl split_vcf.pl -i input_file -o output_dir [OPTION]

    -v,         Verbosity levels, 1-3

스크립트를 실행합니다:

mkdir vcf_files
split_vcf.pl  -i current.vcf -o vcf_files

관련 정보