ファイル行のテキストを増分に置き換える

ファイル行のテキストを増分に置き換える

複数行を含むファイルがあります(行数が不明)。

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"; }

次のような1行のコードで呼び出すことができます。

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%05dTRAN%06d
  • あなたの説明によると、nextcounterファイルから取得した番号が交換に使用される最初の番号のようです。代わりに数字を最初に増やすには、次のcounter++ように変更します。++counter
  • 私の考えでは、nextcounter このファイルは1行と1つの整数しかないファイルのようです。そうでない場合は、スクリプトの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

関連情報