In deze oefening gaan we gebruik maken van find om grote PDF-bestanden te vinden, en deze te doorzoeken met behulp van pdftotext en egrep.

  1. Gebruik find om in de huidige directory alle bestanden te vinden die eindigen op .pdf
  2. Gebruik find om enkel de bestanden uit 1 te filteren die groter 100KB zijn. (Check de man-page!)
  3. Gebruik find om op elk van die bestanden het commando ls -lh uit te voeren.
  4. Het pdftotext-commando kan je gebruiken om het bestand dat je meegeeft als argument om te zetten naar platte tekst (in het geval dat de tekst als dusdanig in de PDF ingebed is). Standaard gaat die tekst worden weggeschreven naar een .txt-bestand, maar je kan er ook voor zorgen dat dit een ander bestand is, door de doelbestandsnaam als tweede argument mee te geven. Indien de doelbestandsnaam - is (een enkel horizontaal streepje), dan gaat deze echter naar standard output geschreven worden. Gebruik pdftotext om de tekst van het bestand A.pdf naar standard output te printen.
  5. Pas het find-commando uit stap 3 aan zodat het voor elk van de PDF-bestanden zijn tekst naar standard output stuurt.
  6. Stuur de tekst van al deze PDFs door egrep, en zoek op alle plaatsen waar de string Bart (case-sensitive) voorkomt.
  7. Het is natuurlijk spijtig: alle bestanden hun tekst is nu achter elkaar geplakt; zodat je niet echt kan zien in welk PDF-bestand dit al-dan-niet stond! Nu, egrep heeft weliswaar de optie om bestandsnamen uit te printen, wat standaard aan staat indien je recursief zoekt in meerdere bestanden, maar in dit geval lezen we van een naamloze standard input. Zoek deze optie, en zet deze eens aan om te kijken wat er gebeurt.
  8. Zoals je merkt: het print gewoon (standard input). Je kan dit label echter customizen met het argument --label, gebruik dit om een custom label Hallo voor elke match te zetten.
  9. We willen nu finaal dat voor elk van de hits in een van de PDF-bestanden het juiste --label meegegeven wordt. Een probleem: op dit punt filtert egrep op de uitvoer van het hele find-commando. Terwijl de link tussen het bestand en de egrep zijn --label argument eigenlijk per bestand dat find vindt zal verschillen. We kunnen ook niet onze gebruikelijke shell-truukjes gebruiken, aangezien egrep effectief elke keer een ander argument moet meekrijgen. Hoe kunnen we hier nu omheen? Wel, eigenlijk wil je voor elke uitvoering van pdftotext een aparte pipe opzetten die een aparte egrep oproep doet. We kunnen dit doen als volgt: in plaats van zomaar pdftotext op te laten starten door find, kunnen we elke keer een niet-interactieve bash laten opstarten (door find) die custom commando’s (inclusief pipes) uitvoert. We kunnen aan die bash vragen om pdftotext te starten met de juiste argumenten, en om die zijn uitvoer door te sturen naar egrep met de juiste commando’s. Dit kan je doen door bash op te starten met de -c optie als volgt: bash -c 'lijst | commandos; meer commandos'. Gebruik dit om aan per gematchte PDF de pdftotext te filteren met een egrep die de juiste bestandsnaam gebruikt voor de --label optie.

Let op: de \; die het einde aangeeft van de -execdir, mag natuurlijk geen deel uitmaken van dit bash-commando, maar moet er na komen).

Let op: als je nu met find ergens een bestandsnaam plakt met {} die spaties bevat, gaat dit normaal zomaar werken, omdat find er voor zorgt dat er slechts 1 argument meegegeven wordt op die plaats. Als je echter zo’n bestandsnaam plakt in zo’n geneste bash -c, weet die bash natuurlijk niet dat die spaties deel uitmaken van een bestandsnaam. Hoe lost je dit op? (En hou er dan rekening mee.)

(Tip: als je dit ooit in het echt zou willen doen, er bestaat een commando pdfgrep dat dit, en meer, voor jullie doet. Dit is enkel om te zien hoe je het zelf had kunnen doen, als dit niet bestond, en om je skills te verbeteren :).)