I used pandoc to convert a Markdown document to a formatted PDF using pdfroff as the engine. The code for this is:

pandoc -s --toc --pdf-engine=pdfroff -o test.pdf test.md

The output file test.pdf renders with the PDF bookmarks and links slightly out of place. About 50 units higher than what they should be. Using jpdftweak, I was able to output a marks.csv file which displays the bookmarks like this:

1;O;Table of Contents;1 FitH 707.000061
1;O;Section 1;2 FitH 607.0
1;O;Section 2;2 FitH 565.040039
2;O;Subsection 2.1;2 FitH 524.08
2;O;Subsection 2.2;2 FitH 484.120026
1;O;Conclusion;2 FitH 443.160034

Using awk, I am able to display just the last column:

awk -F";" '{print $4}' marks.csv | awk -F" " '{print $3}'

and even modify it to even include another field with the corrected FitH values, which then can ouput to another file:

awk -F";" '{print $4}' marks.csv | awk -F" " '{print $3","$3+50}' > dictionary.csv

resulting in


Note: I realize that adding 50 to the values like this causes the numbers to lose their decimal points, but that isn't very important to me, as the physical change in position is quite minimal. I should point out that I can manually change all values using vim and it works just fine. I simply want to automate this with a script (again, preferably with awk).

Because vim can read the pdfroff-generated PDF and display all of the output, I want to use awk to search for the number in the first column of dictionary.csv in the PDF and replace it with the number in the second column. The relevant lines in the pdf all look like this:

<</D [23 0 R /FitH 565.040039]>>endobj

So that 565.040039 appears twice: once as a bookmark value and once as a link value. That number also appears in the first column of dictionary.csv and I want to automatically find and replace all instances of it in the PDF with the second value (615.04), and then repeat this for every line in the dictionary.csv file throughout the pdf.

What is the best way to go about doing this in awk?

  • Welcome to the site. Currently, your question is a little hard to understand. Please be sure to describe not only the steps you want to take, but also give an example on how the ultimate result should look like, as direct comparison to the input as it was before the text processing. Also, it seems like the first part of your question involves steps you have taken already, so you may want to edit them out to make the text easier (and shorter) to read.
    – AdminBee
    Mar 10 at 10:30
  • As an important side-note: Are the parts you want to modify the only lines that look like <</D [ .... /FitH (number)]>>endobj, i.e. would it be an option to directly modify the PDF file by searching for these lines and adding 50 to the number after FitH? Be aware however that anyways this will only work if you don't change the digit width of the number involved because otherwise you will have a corrupt PDF file as the positions (= file offsets) of the following elements will change.
    – AdminBee
    Mar 10 at 10:35

On a modern GNU Linux, you can do from a bash prompt:

awk '{print $NF}' marks.csv | awk -F. '{print "s/"$0"/"($1+50)"."$2"/g"}' >replace.sed
while read -rs f; do
  sed -f replace.sed "$f" >"$(sed 's/\.[pP][dD][fF]$//' <<<"$f")_adjust.pdf"
done < <(/bin/ls *.[pP][dD][fF])
  • pdf files is not simply just a text file you can search and replace like this Mar 14 at 7:09
  • I know. That's what the person asking the question is already doing though. Mar 14 at 14:56
  • Thank you, @WasfiJAOUAD! This solution worked perfectly! Mar 15 at 5:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.