各行から1つの数字を抽出し、ここに別の数字を追加します。

各行から1つの数字を抽出し、ここに別の数字を追加します。

内容は次のようなファイルがあります。

(bookmarks
 ("Cover"
  "#01.djvu" )
 ("Title page"
  "#all_24223_to_00243.cpc0002.djvu" )
 ("Preface"
  "#all_24223_to_00243.cpc0004.djvu" )
 ...

内容を次に変更したいと思います。

(bookmarks
 ("Cover"
  "#2" )
 ("Title page"
  "#3" )
 ("Preface"
  "#5" )
...

前の数字を保持し、前のゼロを.djvu削除してから1を加算します。私はこれを行うためにawkをどのように使用するのか疑問に思います。

ありがとうございます。

答え1

これは仕事に近いですperl

perl -pe 's/"#\K.*?(\d+)\.djvu(?=")/$1+1/ge' <file

変数を含める:

INCR=1 perl -pe 's/"#\K.*?(\d+)\.djvu(?=")/$1+$ENV{INCR}/ge' <file

または:

perl -spe 's/"#\K.*?(\d+)\.djvu(?=")/$1+$incr/ge' -- -incr=1 <file

答え2

GNUawkソリューションは次のとおりです。

awk  '/^ *\(/{print}!/^ *\(/{split($1,aa,"[0-9]+",bb);printf "\"#%s\" )\n", bb[length(bb)]+1}'

または同じですが、読みやすくするために複数行にわたって表示されます。

awk  '/^ *\(/ { print }
     !/^ *\(/ { split( $1, aa, "[0-9]+", bb )
                printf "\"#%s\" )\n", bb[length(bb)]+1 }'
  1. /^ *\!/^ *\(/オプションの空白と開いている角かっこで始まる行と、空白と開いている角かっこを含まない行を含む2つのアドレス規則。

  2. split( $1, aa, "[0-9]+", bb )そうでない行の場合は、2つの配列に分割します。正規表現に一致する区切り文字、正規表現「aa[0-9] +」で行の内容を区切ります。bb最後の要素bbに興味があります。

  3. printf "\"#%s\" )\n"出力ラインをフォーマットして単一の変数を待ちます。

  4. bb[length(bb)]+1bbの最後の要素の値に1を加算します。

答え3

gawk '{
    sub(/#.*\.djvu/, "#" $1 + 1 ".djvu")
    print
}' FPAT='[0-9]+\.djvu' input.txt

アイデアは次のとおりです。

  • 使用.djvuモード(。djvu[0-9]+\.djvuFPATはい:元のファイル名はで#all_24223_to_00243.cpc0002.djvu、抽出された部分はです0002.djvu
  • 古いdjvuファイル名を#.*\.djvu抽出したファイル名に置き換えて、1古いファイル名を増やします。はい:行全体を取得して$0次の#all_24223_to_00243.cpc0002.djvuように置き換えます(文字列を数値に変換する方法により、0002.djvu + 1この式は純粋な数値になります)。ロゴと拡張子を追加します。3gawk#.djvu結果#3.djvu

djvuこのソリューションは、例の入力に示すように、ファイル名が1つの行にのみ機能します。

入力する

(bookmarks
 ("Cover"
  "#01.djvu" )
 ("Title page"
  "#all_24223_to_00243.cpc0002.djvu" )
 ("Preface"
  "#all_24223_to_00243.cpc0004.djvu" )

出力

(bookmarks
 ("Cover"
  "#2.djvu" )
 ("Title page"
  "#3.djvu" )
 ("Preface"
  "#5.djvu" )

関連情報