我有几个 PDF 文件,它们都包含字符串“READING n n”,其中 nn 是相应阅读的编号。每个字符之间正好有一个空格,即“READING 1 0”。
我想编写一个 bash 脚本来搜索每个文件中的数字 n 并将该数字附加到文件的开头。例如,如果脚本在 name.pdf 中找到“READING 1”,则必须将文件名重命名为 1.name.pdf 等。
怎么做?
谢谢
答案1
你的问题的答案取决于这个字符串是否只能出现一次或在所考虑的 PDF 文件中多次。假设它只能发生一次,和有问题的字符串包含为实际文本(即不仅以图形形式),以下方法(需要 GNU Awk 和外部工具pdftotext
)应该可以工作(该示例适用于作为参数传递的单个文件):
#!/bin/bash
OLDNAME="$1"
NUMBER="$(pdftotext "$OLDNAME" - | awk '/R E A D I N G/ {match($0,"R E A D I N G ([[:digit:]])( [[:digit:]])*",a); gsub(" ","",a[2]); print a[1] a[2];}')"
NEWNAME="$NUMBER.$OLDNAME"
mv "$OLDNAME" "$NEWNAME"
检查特定模式match
是否awk
存在,并将该模式的“实际值”输出到输出数组a
,其中条目a[0]
包含整个找到的模式,并a[1]
包含a[n]
括号内的任何子表达式的“实际值”在该模式中,在我们的例子中,数组条目 1 和 2 中的“数字部分” ([[:digit:]])( [[:digit:]])*
(参见例如GNU Awk 用户指南中有关“字符串函数”的部分)。如果结果是个位数,a[2]
则将保留为空,这并不重要。因为在两位数的情况下,数字之间的空格也会匹配,所以我们使用awk
sgsub()
函数在两位数的情况下将其删除。
为了将其应用于多个文件,您可以按如下方式修改脚本,然后将整个 PDF 文件列表作为参数传递(如./rename.sh *.pdf
)。
#!/bin/bash
for OLDNAME in "$@"
do
NUMBER="$(pdftotext "$OLDNAME" - | awk '/R E A D I N G/ {match($0,"R E A D I N G ([[:digit:]])( [[:digit:]])*",a); gsub(" ","",a[2]); print a[1] a[2];}')"
NEWNAME="$NUMBER.$OLDNAME"
mv "$OLDNAME" "$NEWNAME"
done