我正在使用bash脚本来解析PDF中的信息,并使用它来重命名文件(在pdfgrep的帮助下)。但是,经过一些工作后,我在第5行收到了“替换错误”错误,有关如何重新设置格式的想法?
shopt -s nullglob nocaseglob
for f in *.pdf; do
id1=$(pdfgrep -i "ID #: " "$f" | grep -oE "[M][0-9][0-9]+")
id2=$(pdfgrep -i "Second ID: " "$f" | grep -oE "[V][0-9][0-9]+")
$({ read dobmonth; read dobday; read dobyear; } < (pdfgrep -i "Date Of Birth: " "$f" | grep -oE "[0-9]+"))
# Check id1 is found, else do nothing
if [ ${#id1} ]; then
mv "$f" "${id1}_${id2}_${printf '%02d-%02d-%04d\n' "$dobmonth" "$dobday" "$dobyear"}.pdf"
fi
done
答案 0 :(得分:1)
此代码中有几个不相关的错误;更正后的版本可能如下所示:
#!/usr/bin/env bash
shopt -s nullglob nocaseglob
for f in *.pdf; do
id1=$(pdfgrep -i "ID #: " "$f" | grep -oE "[M][0-9][0-9]+") || continue
id2=$(pdfgrep -i "Second ID: " "$f" | grep -oE "[V][0-9][0-9]+") || continue
{ read dobmonth; read dobday; read dobyear; } < <(pdfgrep -i "Date Of Birth: " "$f" | grep -oE "[0-9]+")
printf -v date '%02d-%02d-%04d' "$dobmonth" "$dobday" "$dobyear"
mv -- "$f" "${id1}_${id2}_${date}.pdf"
done
< (...)
不是有意义的bash语法。如果要从process substitution进行重定向,则应分别使用重定向语法<
和进程替换<(...)
。$(...)
生成一个子外壳程序-一个具有自身内存的独立进程,这样,在该子进程中分配的变量就不会暴露给整个较大的外壳程序。因此,如果要使用read
设置的内容可见,就不能将它们放在子外壳中。${printf ...}
不是有意义的语法。也许您想要命令替换?那将是$(printf ...)
,而不是${printf ...}
。但是,使用printf -v varname 'fmt' ...
效率更高,从而避免了完全分叉子shell的开销。|| continue
放在了id1=$(... | grep ...)
命令中,所以我们不再需要测试id1
是否为非空:continue
将触发并导致外壳程序grep
失败时,继续下一个文件。答案 1 :(得分:0)
执行Charles建议创建新文件名的操作,但是您可以考虑采用其他方法来解析PDF文件,以减少对每个文件执行的pdfreg,管道和抓取动作。我的系统上没有pdfgrep,也不知道您的输入文件是什么样子,但是如果我们使用此输入文件:
$ cat file
foo
ID #: M13
foo
Date Of Birth: 05 21 1996
foo
Second ID: V27
foo
和grep -E
代替pdfgrep
,这就是我如何通过只用pdfgrep
读取一次并用{{1}解析输出来从输入文件中获取信息的方法},而不是使用awk
多次读取它,而是使用多个管道和pdfgrep
来提取您需要的信息:
greps
鉴于您可以使用相同的$ grep -E -i '(ID #|Second ID|Date Of Birth): ' file |
awk -F': +' '{f[$1]=$2} END{print f["ID #"], f["Second ID"], f["Date Of Birth"]}'
M13 V27 05 21 1996
方法将输出保存到变量(或数组)中。显然,您可能需要根据read
输出的实际情况来查询awk命令。