
파이프( )로 구분된 대용량(2,500만 행) 데이터 파일이 있습니다 |
. 데이터 공급업체에서 파일을 제공하고 저는 자동화된 작업을 실행하여 파일을 Redshift 데이터베이스에 로드한 다음 데이터를 처리합니다.
다음은 데이터 샘플입니다.
123|110092|ACCT|"HC Account"|"Account1||||||||||||"Mary"|||"|"||||132|"STE|504"|1253|Unspecified Account|||N||ACTV|Active||||04/30/2013|12/31/2099|||||||||||||
지금까지 내가 본 필드 데이터에는 세 가지 세트가 있습니다.
- 텍스트 필드는 큰따옴표(
"
)로 묶입니다. 예:"HC Account"
,"Mary"
및"|"
. 이는 정확하며 데이터는 따옴표 없이 로드되어야 합니다. - 일부 값에는 파이프 구분 기호가 포함됩니다. 예를 들어:
"STE|504"
. 이 경우 필드를 반드시 큰따옴표로 묶어야 합니다. 그렇지 않은 경우 아래 카테고리 3에 속합니다. - 때로는 시작 인용문만 제공되고 종료 인용문이 없는 경우도 있습니다. 예를 들어:
"Account1
.
핵심요약: 로 시작하는 모든 필드는
|"
으로 끝나야 합니다"|
. 그렇지 않고 다른 것이|"
발견되면 첫 번째 큰따옴표를 이스케이프해야 합니다.
따라서 내 데이터 행은 Unix/Python/기타 제안에서 전처리한 후 다음과 같이 편집되어야 합니다.
123|110092|ACCT|"HC Account"|"Account1||||||||||||"Mary"|||"|"||||132|"STE|504"|1253|Unspecified Account|||N||ACTV|Active||||04/30/2013|12/31/2099|||||||||||||
SED를 사용하여 파일을 수정하기 위해 Unix 스크립트를 작성할 계획입니다. 지금까지 작성한 정규식은 다음과 같습니다.
(\|")(?!([a-zA-Z0-9]|\s|\||\/)*("\|))
그러나 이는 문자열을 올바르게 일치시키지 못합니다.
제가 테스트하고 있는 링크는 다음과 같습니다.https://regexr.com/3toib
평균 파일 크기가 3~5GB이고 일반적으로 이러한 파일이 여러 개(10개 이상) 있기 때문에 코드를 가볍게 유지하고 싶습니다.
PS Redshift는 Postgre SQL 엔진을 사용하는 AWS 데이터베이스 서비스이며 적절하게 인용된 필드에서 인용을 제거하고 \
.
또한 코드가 가볍기 때문에 Python/다른 스크립팅 언어로 이 작업을 수행할 의향이 있습니다.
답변1
데이터에 대해 제공한 사양에는 한 가지 큰 문제가 있습니다. 가 유효한 문자열 이거나 "|"
더 정확하게는 따옴표 붙은 문자열이 파이프로 시작할 수 있는 경우 끝 따옴표가 누락된 문자열(예: )에 "Account1
파이프로 시작하는 첫 번째 따옴표 붙은 필드가 있는 경우(예: "|Mary"
) 결정할 방법이 없다모든 경우에"|
가 의 끝 인용문 |"Account1||||||||||||"|
이거나 의 시작 인용문인 경우 |"|Mary"|
.
예를 들어, 가독성을 위해 약간 수정된 단축 버전의 데이터를 사용하면 두 번째부터 인용된 모든 문자열이 파이프로 시작하고 끝 인용문이 누락됩니다.
123|110092|ACCT|"HC Account"|"Account1||||||||||||"|Mary|||"|||||132|"|STE|504|1253
이는 다음과 같이 잘못 해석될 수 있음을 알 수 있습니다.
123
110092
ACCT
"HC Account"
"Account1||||||||||||"
Mary
"|||||132|"
STE
504
1253
이는 정규 표현식, Python 또는 다른 언어를 사용하는 경우 문제가 됩니다. 일반적인 경우의 문제~할 수 있다"해결"할 수 있지만 복잡하며 행당 존재하는 필드 수와 해당 필드의 데이터 구조에 대한 지식을 사용해야 합니다. (그리고 항상 처리되지 않은 극단적인 경우가 있을 수 있습니다.)
즉, 적어도 감지하는 정규식 솔루션은 다음과 같습니다.최대여는 큰 따옴표에서 닫는 따옴표가 누락된 경우 정규식은 각 줄의 시작 부분부터 처리되지 않은 일치하지 않는 첫 번째 여는 따옴표까지 모든 텍스트를 캡처해야 하므로 다중 패스 접근 방식이 필요합니다. (그렇지 않으면 정규식에서 알 수 있듯이 가장 단순한 경우에도 거짓 긍정이 발견됩니다.)
필요한 패스 수는 전체 파일의 행에 대한 여는 따옴표 전용 필드의 최대 수에 1을 더한 것입니다. 각 파일의 처리를 종료하려면 정규 표현식이 파일을 더 이상 수정하지 않는 시기를 감지해야 합니다.
이것은 대부분의 경우에 작동하는 가장 간단한 정규식입니다.
Capturing Group 1 Capturing Group 2
(All previous valid fields) (Unclosed opening quote)
__________________________|_________________________ |
| || |
^((?:(?:(?!")[^|\r\n]*|"[^"\r\n]*"(?=$|\|))(?:$|\|))*+)(")
|____________| |_________________| |______|
| | |
Unquoted field OR Quoted field EOL or hypen delimiter
다음 대체 문자열과 함께 사용하세요.
$1\\$2