2016-03-23 14 views
0

Das Ziel dieser Frage ist, den/PageLabels-Code (source) in einer PDF-Datei für eine andere zu ersetzen. Wir müssen dies tun, weil es einen Fehler im Programm gibt, das die PDF-Datei druckt (wir können das Programm nicht ändern). Von Hand braucht viel Zeit (wir haben 50 pdf-Dateien pro Stunde erstellt).komplexe Zeichenfolge Substitution

Um jedoch pragmatisch zu sein, kann das Beispiel wie folgt zusammengefasst werden.

Alte/PageLabels Code: Befindet sich in einer ursprünglichen Datei namens a.pdf.

Wir verwenden die grep-Funktion den falschen /PageLabels Code zu erhalten:

grep -aPo '/PageLabels\K[^"]*>>]>>' a.pdf 

<</Nums[0<</S/r/St 1>>6<</S/r/St 7>>10<</S/r/St 11>>12<</S/r/St 13>>14<</P(1-)/S/D/St 1>>20<</P(2-)/S/D/St 1>>28<</P(3-)/S/D/St 1>>80<</P(4-)/S/D/St 1>>116<</P(A-)/S/D/St 1>>132<</P(B-)/S/D/St 1>>134<</P(C-)/S/D/St 1>>138<</P(D-)/S/D/St 1>>148<</P(E-)/S/D/St 1>>168<</P(F-)/S/D/St 1>>176<</P(G-)/S/D/St 1>>182<</P(Glossary-)/S/D/St 1>>194<</P(Comments-)/S/D/St 1>>]>> 

Neu/PageLabels Code Wir wollen ersetzen den "Alt-/PageLabels Code" mit dem folgenden. Dies ist das Ergebnis eines anderen Skripts, das die PDF-Datei neu bewertet und den korrekten /PageLabel-Code der PDF-Datei erhält (manuell getestet und verifiziert).

<</Nums[0<</S/r/St 1>>12<</P(1-)/S/D/St 1>>17<</P(2-)/S/D/St 1>>32<</P(3-)/S/D/St 1>>98<</P(4-)/S/D/St 1>>130<</P(A-)/S/D/St 1>>153<</P(B-)/S/D/St 1>>154<</P(C-)/S/D/St 1>>158<</P(D-)/S/D/St 1>>187<</P(E-)/S/D/St 1>>230<</P(F-)/S/D/St 1>>242<</P(G-)/S/D/St 1>>247<</P(Glossary-)/S/D/St 1>>259<</P(Comments-)/S/D/St 1>>]>> 

Es wird in einer anderen b.pdf

genannt Datei gespeichert wird, wissen wir nicht, wie es zu schreiben, mit den Funktion sed.

Alle Ideen würden sehr geschätzt werden.

+2

Können Sie hier die Regeln für die Zuordnung vereinfachen? Fügen Sie auch einige Details hinzu. –

+0

Vielen Dank für das Feedback! gerade gestrichen! –

+0

Was ist "Kette" hier? Was ** speziell ** in diesem Durcheinander von PDF-Müll versuchen Sie zu finden und zu ersetzen? –

Antwort

0

Sie sollten replace statt sed oder regex werden:

#! /bin/bash 
old=$(grep -aPo '/PageLabels\K[^"]*>>]>>' a.pdf) ## Get Old /PageLabels code 
new=$(/tmp/get_correct_code.sh) ## Get New /PageLabels code 
cat a.pdf |replace "$old" "$new" > new_a.pdf 

Aus der Manpage:

DESCRIPTION 
     The replace utility program changes strings in place in files or on the standard input. 

     Invoke replace in one of the following ways: 

      shell> replace from to [from to] ... -- file_name [file_name] ... 
      shell> replace from to [from to] ... < file_name 

UPDATE Wenn Sie es vorziehen sed zu verwenden, können Sie es auf diese Weise versuchen, :

#! /bin/bash 
old=$(grep -aPo '/PageLabels\K[^"]*>>]>>' a.pdf) ## Get Old /PageLabels code 
new=$(/tmp/get_correct_code.sh) ## Get New /PageLabels code 

# To replace $old with $new, first you'd have to escape those characters like [, ], - 
eold=$(echo $old | sed '[email protected]\([][-]\)@\\\[email protected]') 

# Then do the replace using sed 
sed "[email protected][email protected][email protected]" a.pdf > b.pdf 
+0

Vielen Dank für Ihre Antwort. Die Bedingung ist jedoch, die sed-Funktion zu verwenden. –

+0

Aktualisiert mit 'sed' Ansatz. – Quinn

+0

Vielen Dank! Es klappt!. Auch ich fand die gleiche Erklärung hier [link] (http://backreference.org/2009/12/09/using-shell-variables-in-sed/) –

0

Ich verstehe nicht spezifische Informationen, die Sie versuchen, von der Kette zu ersetzen. Aber, wie ich die Kette brechen Ich sehe, dass Variationen gemäß der folgenden Abbildung (Stapel versuchen würde verrückt all die Sonderzeichen zu ersetzen, also in als Bild setzen) Old_new_Chain

Wenn ich richtig gehe davon aus, Sie will pagetags 1>>6 mit 1>>12 ändern und so weiter

Wenn das ist, was Sie wollen, können Sie mit

neuer folgenden ersetzen alten verwenden

cat a.pdf |sed -e 's/1>>20/1>>98/' -e 's/1>>28/1>>130/' und so weiter. Sie können -e weiter oben hinzufügen, solange die Shell es dauert [es hängt von Ihrer * nix Version ab].

Alternativ müssen Sie ein Shell-Skript schreiben, um jede Zeile zu lesen und ein Partikelfeld basierend auf einer bestimmten Logik zu ersetzen. Angenommen, die Zahlen in new_chain variieren von old_chain um einen K-Faktor, der formuliert werden kann.

Wenn Sie alte/neue Daten wie folgt posten können, und lassen Sie mich wissen, wenn es eine Standardabweichung zwischen alt und neu gibt, kann ich weiter helfen.

Hoffe, das hilft.

+0

Zunächst einmal vielen Dank für Ihre Antwort und Ihre Zeit. Leider ist die von Ihnen vorgeschlagene Lösung nicht gültig. Die Annahme ist falsch; Wir wollen die komplette Zeichenfolge ersetzen. Wie Sie sehen können, ist das New_Chain fast gleich dem Old_Chain. In anderen Fällen sind Old_Chain und New_Chain nicht einmal ähnlich. Mit diesem New_Chain wird die Nummerierung in den/PageLabels in einer PDF-Datei neu angeordnet. –

+0

Ich muss erklären, dass, wenn Sie den Code/PageLabels in einem PDF-Dokument ersetzen möchten, die Anzahl der neuen Bytes genau die gleichen wie die ältesten Bytes sein muss. Mit anderen Worten, New_Chain muss die gleiche Größe haben wie Old_Chain.Lucky us, die Anzahl der alten Bytes ist immer größer als die der neuen Bytes (lasst uns die Warum-Frage offen legen). Also fügten wir 0x20 (ASCII-Zeichen: Leerzeichen) hinzu, um die korrekte Größe im New_Chain zu vervollständigen. –