pdfgrep为变量的替换错误错误?

时间:2019-02-16 21:35:41

标签: bash grep

我正在使用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

2 个答案:

答案 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命令。