用于从文件内部重命名文件的Shell脚本

时间:2012-05-21 16:55:53

标签: regex bash file-rename

我一直在论坛和stackoverflow上搜索这个;它必须在某处,但我找不到它。
我在Mac上,使用终端运行shell脚本,根据文件内容重命名一些pdf文件。

我有一个目录,其中包含pdfs,我正在使用opensource pdfbox导出到文本文件。生成的文件与pdf文件具有相同的名称,但以.txt结尾。我创建了文本文件,以便在文件中找到格式为Page xx Question xx的字符串;例如Page 43 Question 2。在这个例子中,我想将pdf文件重命名为pg43_q2.pdf

我认为我想要的正则表达式是这样的: /Page\s+(\d+)Question\s+(\d+) 但我不知道如何读取两个捕获的数字,并将它们保存为一个我可以用作文件名的字符串。

我到目前为止的脚本是:

#!/bin/sh
PDF_FILE_PATH=$1
echo "Converting pdfs at $PDF_FILE_PATH"

find "$PDF_FILE_PATH" -name '*.pdf' -print0 | while IFS= read -r -d '' filename; do
   echo $filename
   java -jar pdfbox-app-1.6.0.jar ExtractText "$filename" "$filename.txt"
   NEWNAME=$(sed -n -e '/Page/s/Page\s+\(\d+\)\s+Question\s+\(\d+\).*$/pg\1_q\2/p' "$filename.txt")
   echo "Renaming pdf $filename to $NEWNAME"
   # I would do this next but the $NEWNAME is empty
   # mv "filename" "PDF_FILE_PATH$NEWNAME"
done

...但是sed命令没有将任何内容放入NEWNAME变量中。

我并不特别关注sed,任何建议都会受到赞赏

对脚本的最新编辑使用以下sed命令:

newname=$(sed -nE -e '/Page/s/^.*Page[[:blank:]]+([0-9]+)[[:blank:]]+Question[[:blank:]]+([0-9]+).*$/pg\1_q\2.pdf/p' "$filename.txt")

大约50%的时间都可以使用,但是当我去重命名文件时,其余的时间newname变量都是空的。

转换文件的第三行有效:

Unit 2 Review Page 257 Question 9  a)  12 (2)(2)(3)

转换后的文件的第三行不起作用:

Unit 2 Review Page 258 Question 16  a)  (a – 4)(a + 7) = a(a + 7) – 4(a + 7)                             = a2 + 7a – 4a – 28                              = a2 + 3a – 28   b)  (2x + 3)(5x + 2) = 2x(5x + 2) + 3(5x + 2)                                 = 10x2 + 4x + 15x + 6                                 = 10x2 + 19x + 6  c)  (–x + 5)(x + 5) = –x(x + 5) + 5(x + 5)                              = –x2 – 5x + 5x + 25                              = –x2 + 25  d)  (3y + 4)2 = (3y + 4)(3y + 4)                     = 3y(3y + 4) + 4(3y + 4)                     = 9y2 + 12y + 12y + 16                     = 9y2 + 24y + 16  e)  (a – 3b)(4a – b) = a(4a – b) – 3b(4a – b)                                = 4a2 – ab – 12ab + 3b2                                = 4a2 – 13ab + 3b2  f)  (v – 1)(2v2 – 4v – 9) = v(2v2 – 4v – 9) – 1(2v2 – 4v – 9)                                      = 2v3 – 4v2 – 9v – 2v2 + 4v + 9                                      = 2v3 – 6v2 – 5v + 9

1 个答案:

答案 0 :(得分:2)

删除了无用的原始答案

echo 'Unit 2 Review Page 257 Question 9  a)  12 (2)(2)(3)'\
| sed -n '/Page/{s/.*Page[ ][ ]*\([0-9][0-9]*\)[ ][ ]*Question[ ][ ]*\([0-9][0-9]*\).*$/pg\1_q\2/;p;q;}'

<强>输出

pg257_q9

echo 'Unit 2 Review Page 258 Question 16  a)  (a  4)(a + 7) = a(a + 7)  4(a + 7)'\
| sed -n '/Page/{s/.*Page[ ][ ]*\([0-9][0-9]*\)[ ][ ]*Question[ ][ ]*\([0-9][0-9]*\).*$/pg\1_q\2/;p;q;}'

<强>输出

pg258_q16

否则,你做对了!

(请注意,对于这两种情况,sed处理都是相同的。)

我添加了一个尾随;p;q}和一个初始{,因此sed脚本只会处理带有'Page'的行,然后退出。

我已经将posix char类扩展为基本术语,即[[:digit:]] = [0-9],并将+替换为重复的初始char类,后跟'零或多'char'*',制作[0-9][0-9]*。我个人的经验是,从OReilly的第二版Sed和Awk(带梳子绑定!)中学习了Sun 3上的sed,就是所有的posix东西都是分散注意力和进一步的错误来源。我在S.O ;-)上显然是少数人,但我愿意承认新的seds有一些很棒的功能,无论如何......

我希望这会有所帮助。

相关问题