用于更改PDF标题的Bash脚本

用于更改PDF标题的Bash脚本,bash,pdf,sed,command-line-interface,Bash,Pdf,Sed,Command Line Interface,我需要更改许多pdf文件的标题。Pdftk工作得很好,我尝试创建一个bash脚本(pdftitle),使其成为一个单一过程: #!/bin/bash newtitle=$2 pdftk "$1" data_dump output "$1".data.txt; sed 's/^InfoKey:\sTitle\nInfoValue:\s.*/InfoKey:\sTitle\nInfoValue:'"$newtitle/" "$1".data.txt > "$1".data.fixed.txt;

我需要更改许多pdf文件的标题。Pdftk工作得很好,我尝试创建一个bash脚本(pdftitle),使其成为一个单一过程:

#!/bin/bash
newtitle=$2
pdftk "$1" data_dump output "$1".data.txt;
sed 's/^InfoKey:\sTitle\nInfoValue:\s.*/InfoKey:\sTitle\nInfoValue:'"$newtitle/" "$1".data.txt > "$1".data.fixed.txt;
pdftk "$1" update_info *.data.fixed.txt output "$1".fixed;
mv "$1".fixed "$1";
rm -f ./*.txt
exit;
因此,在cli上,我将输入

$>pdftitle mypdf.pdf“新标题”

pdftk创建的data.txt有多行,但只有两行相关的行是目标:

...
InfoBegin
InfoKey: Author
InfoValue: Not Me
InfoBegin
InfoKey: Title
InfoValue: Microsoft Word - Old Title.doc
InfoBegin
InfoKey: Creator
InfoValue: PScript5.dll Version 5.2
...
其中后续行需要更换:

...
InfoKey: Title
InfoValue: Relevant New Title
...
不会生成错误消息,但标题保持不变。因此,sed似乎在这里遇到了问题,但我不知道在哪里或如何解决


任何帮助都将不胜感激。

这里有一个使用Awk的重构,它假设
pdftk
可以使用
-
作为伪文件名参数写入和读取stdin/stdout

#!/bin/bash
filename=$1
shift
pdftk "$filename" data_dump output - |
awk -v title="$*" '/^InfoKey: Title/ { t=1 }
    t && /^InfoValue:/ { $0 = "InfoValue: " title; t=0 }1' |
pdftk "$filename" update_info - output "$filename".fixed &&
mv "$filaname".fixed "$filename"
当您看到一个模式时,设置一个标志变量,然后在随后的一行上执行操作(如果设置了该变量)的模式是一种简单且非常常见的Awk习惯用法


不需要尾随分号或结尾显式退出。

@tripleee提供了使bash脚本完美工作的解决方案:

#!/bin/bash
filename=$1
shift
pdftk "$filename" data_dump output |
awk -v title="$@" '/^InfoKey: Title/ { t=1 }
t && /^InfoValue:/ { $0 = "InfoValue: " title; t=0 }1' > data.txt
pdftk "$filename" update_info data.txt output "$filename".fixed &&
mv "$filename".fixed "$filename"
rm ./data.txt

如果不知道您正在运行哪个版本的
sed
,以及在哪个标准库上:
\s
本身不能保证工作(它是一个PCRE扩展;取决于参数,
sed
保证只支持BRE或ERE语法)…无论如何,您能否构建一个不依赖于
pdftk
,而只关注您遇到问题的
sed
位的复制机?这样,其他人就可以在没有您的PDF或事先不知道pdftk输出是什么样子的情况下测试他们的答案。考虑一个函数,它发出您需要转换的输出,比如:<代码> MaqDATA():{Prtff’%s\n’′iFooKEY:标题‘iFooValue:无论……,} < /代码>,然后<代码> MaxDigaSyd…<代码>,以生成一个更独立的。(当然,您还需要明确指定所需的输出)…顺便说一句,
sed
通常不是使用多行匹配的最简单/最佳工具。使用
awk
,甚至本机bash字符串操作原语通常更容易。@Charles Duffy-感谢您的及时回复。我正在使用LinuxMintKDE和sed(GNUSED)4.2.2。至于不使用pdftk和完全依赖sed,我不是一名程序员,我不确定我完全理解你在第二次评论中指示我做什么。它们是关于如何表达更好问题的说明。你的PDF工具在这里并不重要;您的具体问题是如何更改文本文件中的特定行。谢谢@tripleee!经过几次调整后,你的解决方案非常有效。@EdMorton是的,完全同意,我昨天关闭电脑后意识到了这一点。现在已修复。您也需要在此处修复
$*