파일 줄의 텍스트를 증분으로 바꾸기

파일 줄의 텍스트를 증분으로 바꾸기

여러 줄이 포함된 파일이 있습니다(줄 수를 알 수 없음).

DD0TRANSID000019021210504250003379433005533665506656000008587201902070168304000.0AK  0000L00000.00  N          01683016832019021220190212N0000.001683065570067.000000.00000.0000000000000NAcknowledgment                                                                                                                                        
DD0TRANSID000019021210505110003379433005535567606656000008587201902085381804000.0FC  0000L00000.00  N          53818538182019021220190212N0000.053818065570067.000000.00000.0000000000000NFirst Contact                                                                                                                                         
DD0TRANSID000019021210510360003379433005535568006656000008587201902085381804000.0SR  0000L00000.00  N          53818538182019021220190212N0000.0

TRANSID000 텍스트는 위치 3부터 10까지 시작하는 모든 줄에 있으며 이를 1씩 TRAN000066으로 바꿀 수 있어야 합니다.

66은 카운터의 시작을 저장하기 위해 다른 파일(예: nextcounter)에서 가져온 변수입니다. 프로그램이 모든 행을 업데이트하면 마지막 숫자를 캡처하여 다음 카운터 파일을 업데이트할 수 있습니다.

산출

DD0TRAN00066019021210504250003379433005533665506656000008587201902070168304000.0AK  0000L00000.00  N          01683016832019021220190212N0000.001683065570067.000000.00000.0000000000000NAcknowledgment                                                                                                                                        
    DD0TRAN00067019021210505110003379433005535567606656000008587201902085381804000.0FC  0000L00000.00  N          53818538182019021220190212N0000.053818065570067.000000.00000.0000000000000NFirst Contact                                                                                                                                         
    DD0TRAN00068019021210510360003379433005535568006656000008587201902085381804000.0SR  0000L00000.00  N          53818538182019021220190212N0000.053818065570067.000000.00000.0000000000000NStatus Report                                                                                                                                         

답변1

그리고 perl:

perl -spe 's/TRANSID000\K/$n++/e' -- -n=66 < your-file

또는 길이가 5가 되도록 숫자에 0을 채워야 하는 경우(00001, 00010, 00100...):

perl -spe 's/TRANSID\K000/sprintf "%05d", $n++/e' -- -n=66 < your-file

답변2

나는 이 awk스크립트가 그 일을 해야 한다고 생각한다. 가장 간단한 설정이므로 스크립트 내에서 모든 작업을 수행합니다. 그러나 nextcounter를 쉘 변수로 처리할 수 있는 다른 방법을 자세히 살펴보십시오.

BEGIN
    { getline counter < "nextcounter"; }
/TRANSID000/
    {
      replacement_string = sprintf("TRAN%05d", counter++);
      gsub("TRANSID000", replacement_string);
      print;
    }
END
    { printf("%d\n", counter) > "nextcounter"; }

다음과 같은 한 줄의 코드로 호출할 수 있습니다.

cat data | awk -- 'BEGIN { getline counter < "nextcounter"; } /TRANSID000/{ replacement_string = sprintf("TRAN%05d", counter++); gsub("TRANSID000", replacement_string); print; } END { printf("%d\n", counter) > "nextcounter"; }'

참고:

  • TRAN000066OP에서 처음에는 IE와 같이 총 6자리의 문자열을 원한다고 말했지만 예제 출력에는 TRAN00066IE와 같은 5자리의 문자열이 있습니다. 예제 출력을 따랐지만 6자리 정밀도가 필요한 경우 문자열을 변경하면 됩니다 TRAN%05d.TRAN%06d
  • 귀하의 설명에 따르면 nextcounter파일에서 가져온 번호가 교체에 사용되는 첫 번째 번호인 것 같습니다. 대신 숫자를 먼저 늘리려면 다음 counter++과 같이 변경하십시오.++counter
  • 제 생각에는 nextcounter 이 파일은 한 줄과 하나의 정수만 있는 파일인 것 같습니다. 그렇지 않은 경우 스크립트의 BEGIN 및 END부분을 수정해야 합니다.

너가 선호한다면아니요awk 스크립트가 nextcounter파일을 직접 업데이트하고 이러한 nextcounter 값을 쉘 변수로 처리하려면 임시 파일을 사용하여 업데이트된 카운터를 저장하는 더 복잡한 설정이 필요합니다. 이 같은:

tempfile=$(mktemp) ; cat data | awk -v counter="${nextcounter:-0}" -v tempfile="${tempfile}" -- '/TRANSID000/{ replacement_string = sprintf("TRAN%05d", ++counter); gsub("TRANSID000", replacement_string) ; print; } END { printf("%d\n", counter) > tempfile; }' && read nextcounter < "${tempfile}" ; rm "${tempfile}"

고장 설명:

tempfile=$(mktemp) \ # create temporary file
cat data | pipe data to awk ...
    awk -v counter="${nextcounter:-0}" -v tempfile="${tempfile}" -- \ # provide initial counter and tempfile to awk
    '/TRANSID000/ \
        { replacement_string = sprintf("TRAN%05d", ++counter); \
          gsub("TRANSID000", replacement_string) ; \
          print; \
        } \
     END \
        { printf("%d\n", counter) > tempfile; }' \ # write updated counter to temporary file
    && read nextcounter < "${tempfile}" \ # read updated counter into ${nextcounter} shell variable
rm "${tempfile}"

이는 초기 카운터를 가져와 ${nextcounter}마지막에 동일한 변수를 업데이트합니다.

임시 파일을 생성할 수 없는 경우 명명되지 않은 파이프에서 파일 설명자를 사용해 볼 수 있지만 이를 위해서는 Bash v3 이상이 필요합니다.그리고읽기/쓰기 모드로 파이프를 열 수 있는 시스템입니다. Linux에서는 허용하지만 MacOS에서는 허용하지 않습니다. 이것이 다른 Unix-es의 경우인지는 모르겠습니다.

그것은 다음과 같습니다:

exec 9<> <(:) ; cat data | awk -v counter="${nextcounter:-0}" -- '/TRANSID000/{ replacement_string = sprintf("TRAN%05d", ++counter); gsub("TRANSID000", replacement_string); print; } END { printf("%d\n", counter) > "/dev/fd/9"; }' && read nextcounter <&9 ; exec 9<&-

분할:

exec 9<> <(:) # open fd 9 onto unnamed pipe R/W
cat data | \
    awk -v counter="${nextcounter:-0}" -- \
    '/TRANSID000/ \
         { replacement_string = sprintf("TRAN%05d", ++counter); \
           gsub("TRANSID000", replacement_string); \
           print; } \
      END \
         { printf("%d\n", counter) > "/dev/fd/9"; }' \ # write updated counter to fd 9
    && read nextcounter <&9 # read updated counter from fd 9 into ${nextcounter} shell variable
exec 9<&- # close fd 9

답변3

파일이 bash 쉘 유형 "file"에 있는 경우,

inp=66;i=$inp; while read -r ln;do;echo $ln sed -E "s/TRANSID000/TRAN0000$i/i";let i++;done<file

관련 정보