提取每行中的一个数字并向其添加另一个数字

提取每行中的一个数字并向其添加另一个数字

我有一个文件,其内容是

(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. split( $1, aa, "[0-9]+", bb )对于没有的行,请将其拆分为两个数组。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(此表达式结果为纯数字3,因为字符串到数字的转换在 中如何工作gawk)。添加#标志和.djvu扩展名。结果: #3.djvu

此解决方案仅适用于具有一个djvu文件名的行,如示例输入中所示。

输入

(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" )

相关内容