
여러 줄이 포함된 파일이 있습니다(줄 수를 알 수 없음).
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"; }'
참고:
TRAN000066
OP에서 처음에는 IE와 같이 총 6자리의 문자열을 원한다고 말했지만 예제 출력에는TRAN00066
IE와 같은 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