위치를 파일의 다른 위치로 바꾸기

위치를 파일의 다른 위치로 바꾸기

고정 레코드 길이(~2500)의 플랫 파일이 있습니다.

H20190105                         
D0012345APPLE INC      100001072010
D0008912SAMSUNG        450023082005
T0001245678                       
  • 위치 2-8 A/C#(왼쪽이 0으로 채워짐)
  • 계좌명 9~23자리 (오른쪽 공백 채우기)
  • 나머지 24개 필드 배치

A/C#에서 선행 0을 제거하여 파일의 계정 이름 필드(위치 9-23)를 ACCT_A/C#으로 마스킹해야 합니다.

원하는 결과는 다음과 같습니다

H20190105
D0012345ACCT_12345     100001072010
D0008912ACCT_8912      450023082005
T0001245678

다음 명령을 사용했지만 A/C#에서 선행 0을 제거할 수 없습니다.

awk '/^D/{$0=substr($0,1,8)"ACCT_"substr($0,2,7)"  "substr($0,24,length($0))} 1' FILE.TXT > OUT.TXT

int(substr($0,2,7))다음 필드 위치를 변경하려면 트림 제로를 사용하십시오 .

원하는 결과를 얻는 데 도움을 줄 수 있는 사람이 있나요?

답변1

다소 짧은 awk문장:

$ awk '/^D/ { nr = substr($0,2,7); $0 = sprintf("D%07dACCT_%-10d%s", nr, nr, substr($0,24)) } { print }' file
H20190105
D0012345ACCT_12345     100001072010
D0008912ACCT_8912      450023082005
T0001245678

이 코드는 첫 번째 위치에 a가 있어서 awk수정해야 하는 행을 감지 합니다.D

sprintf()새 줄은 뒤에 0으로 채워진 숫자, 그 뒤에 D같은 숫자의 문자열(현재는 0으로 채워지지 않음), 마지막으로 줄의 위치 24 안팎으로 구성됩니다.ACCT_

모든 줄을 인쇄합니다(위와 같이 수정되거나 전혀 수정되지 않음).

답변2

$ perl -pe 's/^(D)(.{7})(.{12})/sprintf("%s%s%s%-7s",$1,$2,"ACCT_",$2+0)/e' input.txt 
H20190105                         
D0012345ACCT_12345     100001072010
D0008912ACCT_8912      450023082005
T0001245678                       

이는 Perl의 연산자 e수정자를 사용하여 s/LHS/RHS/RHS를 Perl 코드로 실행합니다. $2+0$2를 0으로 채워진 문자열에서 숫자로 암시적으로 변환합니다. 그러면 선행 0이 모두 자동으로 제거됩니다. 이 sprintf()형식을 사용하면 출력 행의 필드 길이가 입력과 정확히 동일합니다.


또는 다음 awk줄 중 하나를 수정하세요.

$ awk '/^D/{$0=substr($0,1,8)"ACCT_"sprintf("%-7s",substr($0,2,7)+0)"  "substr($0,24,length($0))} 1' input.txt 
H20190105                         
D0012345ACCT_12345    100001072010
D0008912ACCT_8912     450023082005
T0001245678                       

awk스프린트f도 있습니다. IMO 이것은 Perl 버전보다 읽고 이해하기가 더 어렵습니다. YMMV.

awkPerl 버전과 유사한 다른 버전:

$ awk '
   /^D/ {
     ac=sprintf("%-7s",substr($0,2,7)+0);
     $0=gensub("^(D)(.{7})(.{12})","\\1\\2ACCT_"ac,1)
   }
   1' input.txt 
H20190105                         
D0012345ACCT_12345     100001072010
D0008912ACCT_8912      450023082005
T0001245678                       

제로 패딩을 제거할 필요가 없으면 다음과 같이 할 수 있습니다 sed.

$ sed -E -e 's/^(D)(.{7})(.{12})/\1\2ACCT_\2/' input.txt 
H20190105                         
D0012345ACCT_0012345   100001072010
D0008912ACCT_0008912   450023082005
T0001245678                       

답변3

$ awk 'NF>1{$0=sprintf("%sACCT_%-11d%s", substr($0,1,8), substr($0,2,7), substr($0,24))} 1' file
H20190105
D0012345ACCT_12345      100001072010
D0008912ACCT_8912       450023082005
T0001245678

관련 정보