배쉬 스크립트

배쉬 스크립트

최대 백만 개의 레코드가 포함된 공급업체의 파일이 여러 개 있습니다.

이 파일은 원래 Windows 환경에서 왔으며 우리가 파일을 얻었을 때 텍스트 필드 중간에 있는 줄 바꿈으로 인해 레코드에 잘못된 분할이 있었습니다.

나는 이것이 Linux로 전송하는 동안 문자가 개행 문자로 해석되었기 때문에 발생한 것이라고 생각하지만 원본 Windows 파일을 본 적이 없기 때문에 확실하지 않습니다.

나에게 필요한 것은 한 줄의 구분 기호 수를 계산하고 지정된 임계값 미만인 경우 레코드 끝에서 줄 바꿈을 제거하는 루틴입니다. 예를 들어, 레코드에 29개의 열이 있고 28개의 "파이프" 구분 기호("|")가 있어야 한다는 것을 알고 있습니다. 잘못된 줄 바꿈으로 인해 데이터를 얻으면 두 개의 레코드를 얻게 되며 그 중 하나에는 10개의 필드와 9개의 구분 기호가 있습니다. 두 번째에는 19개의 필드와 18개의 구분 기호가 포함되어 있습니다. 다음은 보안상의 이유로 데이터를 변경하는 예입니다.

9999999999|Duck Donald|87|||999999999|9999999999|XX999999|||Z99999|999 Planet Ln|||Trumpet
ville|ZZ|99999||||||ZZ|P|9999999999|F|||

줄은 "Trumpetville"이라는 단어로 나누어져 있습니다. 개행 문자가 삽입되었거나 잘못 해석되었기 때문입니다. 다시 구분 기호를 세고 구분 기호 수가 지정된 임계값 아래로 떨어지면 줄 바꿈을 제거하는 woutine을 찾습니다.

답변1

노력하다:

sed -e :1 -e 's/|/|/28;t' -e 'N;s/\n//;t1' < your-file

또는:

awk -F'|' '{while (NF < 29 && (getline nextline) > 0)
   $0 = $0 nextline; print}' < your-file

텍스트에 CRLF Microsoft 줄 구분 기호가 있는 경우 dos2unix를 사용하여 먼저 파일을 처리해야 할 수도 있습니다.

답변2

필요하지 않다고 가정하면캐리지 리턴 및 줄 바꿈데이터에 따르면 사실입니다아니요필드 시작 부분에 나타나며 다음을 수행할 수 있습니다.

예상 교체캐리지 리턴 및 줄 바꿈Linux EOL 라인의 끝에서,만약에.

이는 파이프 문자 다음에 발생해야 합니다. 직접 또는 공백으로 구분됩니다. 따라서 문자열 "pipe space CRLF" 및 "pipe CRLF"를 "pipe space LF" 또는 "pipe LF"로 바꾸십시오.

0x7C 0x20 0x0D 0x0A그리고0x7C 0x0D 0x0A

도착하다

0x7C 0x20 0x0A그리고0x7C 0x0A

이제캐리지 리턴 및 줄 바꿈나머지는 데이터에 있습니다. "CRLF" 문자열을 공백이나 null 값으로 바꿉니다.

0x0D 0x0A도착하다0x20

편집하다:

예상되는 EOL은 두 파이프 사이에 있어야 합니다.

|데이터|캐리지 리턴 및 줄 바꿈

|데이터|

0x7C 0x0D 0x0A 0x7C

답변3

배쉬 스크립트

원래 답변이 실제로 원하는 것이 아니라는 것을 읽었습니다. 아래 스크립트를 참조하세요. 이는 입력 파일의 요소 수를 미리 알고 있는 경우에만 작동합니다.

#!/bin/bash

infile=/home/wokie/duck.txt
outfile=/home/wokie/duck2.txt
# Define the amount of elements/columns in a row
maxelem=28

# Read the file, strip all newline characters and create one big variable
inputOneline=$(cat $infile | dos2unix | tr -d '\n')

count=0
# Read through the variable and split elements
for element in ${inputOneline//|/ }
  do
  if [ $count -lt $maxelem ]
    then
      # Write element to outfile while suppresing newline (-n) 
      echo -n "$element|" >> $outfile
      count=$[$count +1]
    else
      # Write newline to outfile when maximum elements is reached
      echo >> $outfile
      count=0
  fi
done

전체 아이디어는 먼저 모든 개행 문자를 제거한 다음 개행 문자가 포함된 새 파일을 올바른 위치에 배치하는 것입니다.

도스2유닉스

이 스크립트는 dos2unix라는 훌륭한 도구를 사용합니다. 파일 이름만 인수로 사용하여 dos2unix를 실행하면 입력(Windows) 파일이 자동으로 unix 형식으로 변환됩니다.

-id 매개변수를 사용하여 도구를 시작하면 CRLF 발생 횟수가 계산됩니다. 예를 들면 다음과 같습니다.

[test@testsystem ~]$ dos2unix -id /home/wokie/test2.txt 5 /home/wokie/test2.txt

샘플 파일에는 5번 나타납니다.

dos2unix 도구는 여기에서 찾을 수 있습니다: https://sourceforge.net/projects/dos2unix/. 대부분의 배포판은 dos2unix를 표준으로 제공하거나 apt-get 또는 dnf를 사용하여 설치할 수 있는 가능성을 제공합니다.

관련 정보