Sed + for in Skript verwenden

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
Tintom
Moderator
Beiträge: 3033
Registriert: 14.04.2006 20:55:15
Wohnort: Göttingen

Sed + for in Skript verwenden

Beitrag von Tintom » 02.05.2020 19:53:18

Hallo zusammen,
meine Kenntnisse in sed sind recht rudimentär und deswegen habe ich Schwierigkeiten bei Folgendem:

Ich habe eine recht umfangreiche Textdatei (Markdown-Text), bei der ich Überschriften von einzelnen Absätzen austauschen will. Ziel ist in der Textdatei ein Inhaltsverzeichnis mit HTML-Links anzulegen.

Die Dateien haben etwa folgenden Aufbau:

TOC:
## Überschrift 1 mit Buchstaben Sonderzeichen und Leerzeichen
## Überschrift 2 mit Buchstaben Sonderzeichen und Leerzeichen
(...)
TOC2:
## Überschrift 1 mit Buchstaben Sonderzeichen und Leerzeichen sowie HTML-Tags
## Überschrift 2 mit Buchstaben Sonderzeichen und Leerzeichen sowie HTML-Tags
(...)
Mein Skript sieht so aus:

#!/bin/bash
#
TOC=/dev/shm/toc
TOC2=/dev/shm/toc_fertig
#
for i in `cat ${TOC}`;do
sed -i 's/"${i}"/"`grep ${i} ${TOC2}`"/g' /dev/shm/markdown.txt;
done


Starte ich das Skript in der Konsole bekomme ich keine Rückmeldung, d.h. das Skript läuft, aber es beendet sich nicht und wirft auch keine Fehlermeldungen raus.
Spiele ich mit den Parametern ' und " im Skript herum hagelt es Fehlermeldungen in der Art sed: -e Ausdruck ... Unbekannte Option für »s«.

Ich weiß nun nicht, ob ich sed falsch aufrufe oder mein for-Konstrukt falsch ist.

Kann mich jemand auf den richtigen Weg bringen?

Danke!

Benutzeravatar
Meillo
Moderator
Beiträge: 8818
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Sed + for in Skript verwenden

Beitrag von Meillo » 02.05.2020 20:24:18

Code: Alles auswählen

#!/bin/bash
#
TOC=/dev/shm/toc
TOC2=/dev/shm/toc_fertig
#
for i in `cat ${TOC}`;do
	sed -i 's/"${i}"/"`grep ${i} ${TOC2}`"/g' /dev/shm/markdown.txt;
done
Da stimmt schon so einiges nicht.

Sed arbeitet schon von alleine zeilenweise, du brauchst also gar keine for-Schleife. Wenn du sed auf die Datei anwendest, werden die sed-Befehle fuer jede Zeile der Datei abgearbeitet.

Was du, wie mir scheint, machen willst, ist es, in einer Datei (toc) spezielle Zeilen ersetzen durch entsprechende Zeilen in der anderen Datei (toc_fertig). Mir scheint, dass die erste Datei sehr viel mehr Inhalte hat, darunter eben auch ein paar Ueberschriften. Die zweite Datei enthaelt nur die Ueberschriften, die einen identischen Anfang haben, am Ende aber noch mehr dranhaengen haben. -- Ist diese Analyse korrekt?


Sed ist dafuer vielleicht nicht das beste Werkzeug. Falls die Ueberschrift und der zusaetzliche HTML-Code eindeutig getrennt sind, koenntest du z.B. join(1) verwenden. Sonst wuerde ich wohl awk nehmen, weil man damit einfach mehr Flexibilitaet hat, z.B. auch aus mehreren Dateien gleichzeitig lesen kann.

Es wuerde helfen, wenn du nochmal genauer -- und am besten mit realen Inhaltsschnipseln -- beschreibst wie die Situation aussieht und was du haben willst. (Nur so abstakte Pseudo-Beispiele zu liefern ist schwierig, wenn du gar nicht weisst worauf es ankommt, also was du weglassen oder pseudonymisieren kannst und was eben nicht.)


Wenn du nur eine Loesung brauchst, dann lass am besten uns was entwicklen, das wir dir dann erklaern, damit du es nachvollziehen kannst.

Wenn es dir aber vor allem wichtig waere, etwas zu lernen, und das Projekt nur ein Uebungsbeispiel ist, dann muessen wir grundsaetzlicher anfangen, denn in obigem Codeschnipsel zeugt manches von fehlendem Grundverstaendnis.

Was du suchst musst du entscheiden. Ich helfe gerne in jedem Fall mit.



EDIT:

Ach nein, ich glaube, jetzt verstehe ich es: In `markdown.txt' ist der komplette Text. Die Zeilen in `toc' finden sich darin. Diese Zeilen sollen aber ersetzt werden durch die entsprechenden Zeilen aus `toc_fertig'. Das laesst sich machen ...
Use ed once in a while!

Benutzeravatar
Meillo
Moderator
Beiträge: 8818
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Sed + for in Skript verwenden

Beitrag von Meillo » 02.05.2020 20:42:49

Meillo hat geschrieben: ↑ zum Beitrag ↑
02.05.2020 20:24:18
EDIT:

Ach nein, ich glaube, jetzt verstehe ich es: In `markdown.txt' ist der Komplette Text. Die Zeilen in `toc' finden sich daran. Diese Zeilen sollen aber ersetzt werden durch die entsprechenden Zeilen aus `toc_fertig'. Das laesst sich machen ...
Hier ein Script, das die Zusammenfuehrung erledigt. Das Ergebnis wird ausgegeben. Man muss es dann noch in eine Datei umlenken.

Code: Alles auswählen

#!/bin/sh

if [ $# -ne 3 ]; then
        echo "Usage: $0 MDFILE TOC1 TOC2" >&2
        exit 1
fi

awk -v toc1="$2" -v toc2="$3" '

function replace(s) {
        if (s in toc) {
                return toc[s]
        } else {
                return s
        }
}

BEGIN {
        # read both toc files and connect them
        while (getline a <toc1) {
                getline b <toc2
                toc[a] = b
        }
}

{
        # process each line
        print replace($0)
}


' "$1"
Use ed once in a while!

Benutzeravatar
Meillo
Moderator
Beiträge: 8818
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Sed + for in Skript verwenden

Beitrag von Meillo » 02.05.2020 20:46:10

Hier noch etwas kompakter:

Code: Alles auswählen

#!/bin/sh

if [ $# -ne 3 ]; then
        echo "Usage: $0 MDFILE TOC1 TOC2" >&2
        exit 1
fi

awk -v toc1="$2" -v toc2="$3" '

BEGIN {
        while (getline a <toc1 && getline b <toc2) {
                toc[a] = b
        }
}

{
        print ($0 in toc) ? toc[$0] : $0
}

' "$1"
Use ed once in a while!

Antworten