2016-06-01 6 views
0

Ich habe ein Skript, das PDFs nach bestimmten Fehlern durchsucht und deren Instanzen in einer Datei mit der entsprechenden Seitennummer protokolliert. (Mit Pdfgrep, wenn Sie interessiert sind.) Die PDFs sind für Abschnitte eines Buches und sind daher nicht immer im Druck von 1 nummeriert. Für jeden Fehler im Protokoll möchte ich die Nummer anzeigen, die tatsächlich auf der Seite gedruckt wird , die Folio genannt wird, um die Bezugnahme zu erleichtern, anstatt die PDF-Seitenzahl, die ich derzeit habe.Inkrementiere Zahlen in einer Datei, die einem bestimmten Muster um einen festen Betrag entsprechen

Nicht alle Zeilen im Protokoll sind Fehler. Hier einige Beispiel-Ausgabe:

Searches run on vol1.pdf, 01-06-2016 

S01 SPACED SEMICOLON 
77: ences          Unit for Italian Studies: ; Dir C. KENNEDY  SUMMERS, P. M., Tropical Veterinary Science 
143:BRAC Business School: ; Head Dr MD    BISWAS          Internet: www.diu.ac.bd 
143:BRAC Development Institute: ; Dir Prof.  Dir for Student Welfare: GOUTAM KUMAR   Private control 
261:Basic Institute of Biosciences: ; tel. (12)  College of Business Administration: Ir MARIA Academic year: February to December 
261:Basic Institute of Exact Sciences: ; tel.              atinguetá 
261:Basic Institute of Human Sciences: ; tel.  Committee on Ethics: Dr RODRIGO RICCI   Vice-Rector: MARILZA VIEIRA CUNHA RUDGE 
299:Documentation sur les Traditions et les              Interpreters (ASTI): ; Dir Dr ETIENNE ZÉ 
328:    Political Science:   CRESPI, B. J.       ing: ; tel. (604) 291-5240; f. 1987; Dir Dr R. 

Die Datei im Beispiel beginnt bei p81, in dem Skript als $ Folio erfasst. Für alle Zeilen, die mit einer Zahl zwischen 2 und 4 Ziffern beginnen, gefolgt von einem Doppelpunkt, möchte ich diese Zahl durch N + ($ folio -1) ersetzen.

Ich hatte gedacht, eine Schleife wie diese zu verwenden, um das Protokoll Zeile für Zeile zu durchlaufen.

while read line 
    do 
     # magic here 

    done < $log 

Ich bin ziemlich neu in der Befehlszeile Sachen. Mein erster Gedanke war, grep^[0-9] {2, 4} zu verwenden und das auch irgendwie auf eine Variable zu speichern, dann zu berechnen, aber während des Googelns scheint es vielleicht sinnvoller zu sein, sed oder awk zu verwenden. Ich habe viele Antworten gefunden, die zum Erhöhen von Zahlen um 1 usw. führen, aber nichts dergleichen, und ich bin mir nicht sicher, wie es weitergehen soll. Für Vorschläge wäre ich sehr dankbar.

Der $ Folio-Wert unterscheidet sich jedes Mal, also sammle ich das über Benutzereingabe zusammen mit dem $ log-Dateinamen, um zu arbeiten.

Die Header (z. B. S01 SPACED SEMICOLON) müssen intakt bleiben.

+2

shell ist zum Erstellen/Löschen von Dateien und Prozessen und Sequenzieren von Aufrufen von Befehlen, nicht zum Manipulieren von Text. grep dient nur dazu, einen regulären Ausdruck in einer Datei zu finden und das Ergebnis auszudrucken. sed dient nur dazu, einfache Substitutionen einzelner Zeilen zu machen (es gibt Sprachkonstrukte, die mehr tun, aber sie sind seit der Mitte der 1970er, als awk erfunden wurde, veraltet). awk ist für jede andere Textmanipulationsaufgabe, einschließlich was auch immer Sie versuchen, zu tun. Bitte [bearbeiten] Sie Ihre Frage, um zu klären, wo der Folio-Wert in Ihrer Eingabedatei erscheint, und schließen Sie die erwartete Ausgabe bei dieser Beispieleingabe ein. –

+0

@EdMorton 'awk ist für jede andere Textmanipulationsaufgabe', weiß ich nicht, manchmal hat Perl bessere Funktionalität. – 123

+0

@EdMorton Ich meine nicht unbedingt nur kürzer, zum Beispiel ist das 'e' Flag auf Substitutionen in bestimmten Situationen sehr nützlich, wo ich nicht weiß, dass awk etwas Vergleichbares hat. – 123

Antwort

1

Meine Perl ist ein bisschen unbeholfen, aber:

perl -nle 's/^(\d{2,4}):/$1+82 . ":"/e && print' log 

159: ences          Unit for Italian Studies: ; Dir C. KENNEDY  SUMMERS, P. M., Tropical Veterinary Science 
225:BRAC Business School: ; Head Dr MD    BISWAS          Internet: www.diu.ac.bd 
225:BRAC Development Institute: ; Dir Prof.  Dir for Student Welfare: GOUTAM KUMAR   Private control 
343:Basic Institute of Biosciences: ; tel. (12)  College of Business Administration: Ir MARIA Academic year: February to December 
343:Basic Institute of Exact Sciences: ; tel.              atinguetá 
343:Basic Institute of Human Sciences: ; tel.  Committee on Ethics: Dr RODRIGO RICCI   Vice-Rector: MARILZA VIEIRA CUNHA RUDGE 
381:Documentation sur les Traditions et les              Interpreters (ASTI): ; Dir Dr ETIENNE ZÉ 
410:    Political Science:   CRESPI, B. J. 

Das sagt ... „Prozess die Datei‚log‘und wenn Sie eine Zeile finden, die mit 2-4 Ziffern und einem Doppelpunkt beginnt, berechnen eine Ersatzleitung. diese Linie muss die Nummer haben Sie und 82 und einen Doppelpunkt gefunden. Wenn Sie eine so finden, ausdrucken“

Es ist irgendwie schwer zu erklären, aber alles in (...) auf der linken Seite wird nummeriert und steht auf der rechten Seite als $n zur Verfügung. Also die 2-4 Ziffern, die wir finden, werden als $1 im Ersatz verfügbar.

Das Bit, das die Magie tut, ist das e was bedeutet „etwas mehr Perl führen Sie den Ersatz-String zu berechnen“.

Wenn die anderen Zeilen (d. H. Die Header und Zeilen, die nicht mit Zahlen beginnen) ebenfalls intakt passieren sollen, ändern Sie && in ;. Und in der Tat, wie @ 123 Punkte freundlich in den Kommentaren aus, wenn Sie das wollen, können Sie gehen mit:

perl -pe 's/^(\d{2,4}):/$1+82 . ":"/e' log 

Searches run on vol1.pdf, 01-06-2016 

S01 SPACED SEMICOLON 
159: ences          Unit for Italian Studies: ; Dir C. KENNEDY  SUMMERS, P. M., Tropical Veterinary Science 
225:BRAC Business School: ; Head Dr MD    BISWAS          Internet: www.diu.ac.bd 
225:BRAC Development Institute: ; Dir Prof.  Dir for Student Welfare: GOUTAM KUMAR   Private control 
343:Basic Institute of Biosciences: ; tel. (12)  College of Business Administration: Ir MARIA Academic year: February to December 
343:Basic Institute of Exact Sciences: ; tel.              atinguetá 
343:Basic Institute of Human Sciences: ; tel.  Committee on Ethics: Dr RODRIGO RICCI   Vice-Rector: MARILZA VIEIRA CUNHA RUDGE 
381:Documentation sur les Traditions et les              Interpreters (ASTI): ; Dir Dr ETIENNE ZÉ 
410:    Political Science:   CRESPI, B. J. 
+0

Sie können die Flags "l" und "n" überspringen und "&& print" entfernen und einfach das Flag "p" verwenden. Es sei denn, sie wollen nicht die Header ... – 123

+1

@ 123 Vielen Dank für Ihre Erkenntnisse. Ich habe sie hinzugefügt. –

+0

Danke, ja, ich möchte die Header behalten. Ich werde den ursprünglichen Beitrag bearbeiten, um das klarzustellen. – lambchop

0

Eine awk Lösung könnte so aussehen:

#!/bin/bash 

# The awk script below relies on features of POSIX awk that are not present 
# in legacy awk and are not enabled by default in some other awks (e.g. 
# older GNU awk). POSIX_AWK identifies a POSIX-compliant awk to use. 
POSIX_AWK='/usr/bin/awk --posix' 

# ... 

folio=7 

# ... 

$POSIX_AWK -F ':' -v offset=$(($folio - 1)) ' 
/^[0-9]{2,4}:.*/ { sub(/[0-9]*/, $1 + offset) } 
        { print } 
' $1 

Das awk Programm ist in das Shell-Skript eingebettet.Arithmetische Expansion wird verwendet, um den Zeilennummern-Offset zu berechnen, der dann einer awk Variablen über eine -v Option vor-zugewiesen wird (Bash tut diesen Teil, wenn er die awk Befehlszeile erweitert). Die Option -F ':' teilt awk mit, den Doppelpunkt als Feldtrennzeichen zu verwenden. Dies wird als ein Komfort zum Extrahieren der führenden Nummer aus nummerierten Zeilen verwendet. Das Programm liest jede Zeile der durch $log angegebenen Datei, ersetzt die eingestellte Zeilennummer in Zeilen, die eine Zeilennummer haben, und druckt in jedem Fall die möglicherweise modifizierte Zeile auf die Standardausgabe.

+1

'GNU awk erfordert --posix, um Intervall-Quantifikatoren in Regexes zu unterstützen' Nein, es tut nicht ... – 123

+0

@ 123, nun, wenn Sie Nissen auswählen möchten, können Sie stattdessen das spezifischere '--re-Intervall' verwenden. Die Dokumente sagen konkret: "Interval Ausdrücke sind nur verfügbar, wenn entweder --posix oder --re-interval auf der Kommandozeile angegeben ist, und das Programm nicht mit GNU' awk' funktioniert, wenn '--posix' weggelassen wird und '--re-interval' wird nicht verwendet. Ich habe den Code Kommentar geklärt. –

+0

@JohnBollinger RE-Intervalle wurden standardmäßig seit gawk 4.0 aktiviert, das jetzt mehrere Jahre alt und selbst veraltet ist. Wenn du ein prähistorisches Gawk hast und es nicht schaffen kannst, ein neues zu bekommen, dann solltest du '--re-interval' anstelle von' --posix' verwenden, da letzteres alle anderen gawk-spezifischen Funktionen deaktiviert, z. 'gensub()'. Fügen Sie auch keine Skripte in doppelte Anführungszeichen ein, da dies den restlichen Code kompliziert und zerbrechlich macht. Verwenden Sie immer einfache Anführungszeichen und sehen Sie sich http://cfajohnson.com/shell/cus-faq-2.html#Q24 an Wie verwende ich Shell-Variablen in awk-Skripten? –

Verwandte Themen