레코드는 PIPE로 구분된 파일의 다음 줄로 이동합니다.

레코드는 PIPE로 구분된 파일의 다음 줄로 이동합니다.

다음 형식의 파이프로 구분된 파일이 있습니다.

1|ABC|11|DEF|111
2|ABC|22|PQR
ST
UW|222
3|ABC|33|XYZ|333
4|ABC|44|LMN|444

2이제 이 레코드를 테이블에 삽입하려고 할 때부터 시작하는 행의 경우 레코드만 삽입되고 PQR시작하는 행부터 레코드 삽입이 시작됩니다.4

테이블에 행 2를 성공적으로 삽입하는 데 도움이 되는 모든 행 2 레코드를 단일 행에 넣는 명령이 있다면 감사하겠습니다.

답변1

레코드에 포함된 개행 문자를 공백으로 바꾸려면 GNU를 사용하십시오 awk.

num_fields=4
awk -v RS='([^|]*\\|){'"$num_fields"'}[^|]*\n' '
  {
   n = split(RT, a,"|"); 
   for (i=1; i<=n; ++i)
   {
      gsub("\n", " ", a[i]); 
      printf "%s%s", a[i], i==n?"\n":"|"
   }
  }' file

이것은

1|ABC|11|DEF|111 
2|ABC|22|PQR ST UW|222 
3|ABC|33|XYZ|333 
4|ABC|44|LMN|444 

여기서의 비결은 awk임의의 레코드 구분 기호에 대한 GNU 지원을 사용하여 하나를 4개의 파이프 종료 필드와 줄 바꿈 종료 필드로 정의하여 모든 필드에 내장된 파이프(pass through RS='([^|]*\\|){4}[^|]*\n')가 포함되는 것을 허용하지 않는 것입니다.

이 사양을 준수하는 실제 레코드 구분 기호는 를 통해 액세스할 수 있습니다 RT. RT파이프를 통해 배열로 분할하고 a, 각 요소에서 포함된 개행 문자를 제거하고 a, 마지막으로 요소를 다시 결합하여 레코드를 다시 작성하면 되는 간단한 문제입니다.a

답변2

이 미친 파일 형식에서 조각을 추출하는 한 가지 방법은 Perl을 사용하는 것입니다.

#!/usr/bin/perl
#
use warnings;
use strict;

undef $/;
my $file = <>;

while ($file =~ /^(.*?\|.*?\|.*?\|.*?\|.*?)$/mscg) {
    my $fields = $1;
    $fields =~ s/\n(.)/\\n$1/sg;
    print "$fields\n";
}

코드는 전체 파일을 메모리에 넣은 다음 |한 줄에 5개의 구분된 필드로 다시 청크합니다. 포함된 개행 문자는 \n.

스크립트가 호출되면 이를 repipe.pl사용하여 datafile.perl repipe.pl datafile

어려움을 느낀다면 다음과 같이 한 줄로 포함할 수 있지만 유지 관리에는 큰 도움이 되지 않습니다.

perl -e 'undef $/; $file = <>; while ($file =~ /^(.*?\|.*?\|.*?\|.*?\|.*?)$/mscg) { $fields = $1; $fields =~ s/\n(.)/\\n$1/sg; print "$fields\n"; }' datafile

다음은 샘플 데이터 파일의 출력입니다.

1|ABC|11|DEF|111
2|ABC|22|PQR\nST\nUW|222
3|ABC|33|XYZ|333
4|ABC|44|LMN|444

관련 정보