다음 형식의 파이프로 구분된 파일이 있습니다.
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