我有一个文件,其内容是
(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 }'
/^ *\
和!/^ *\(/
是两个地址规则,涵盖以可选空格和左括号开头的行...以及不包含空格和左括号的行。split( $1, aa, "[0-9]+", bb )
对于没有的行,请将其拆分为两个数组。aa
是由正则表达式“[0-9]+”分隔的行内容,是与bb
正则表达式匹配的分隔符。最后一个元素bb
是您感兴趣的。printf "\"#%s\" )\n"
格式化输出行,等待单个变量...bb[length(bb)]+1
bb 的最后一个元素的值加上 1。
答案3
gawk '{
sub(/#.*\.djvu/, "#" $1 + 1 ".djvu")
print
}' FPAT='[0-9]+\.djvu' input.txt
想法如下:
- 使用
.djvu
模式(djvu
[0-9]+\.djvu
FPAT
。例子: 原文件名是#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" )