ubuntuusers.de

sed - Dopplungen in einer html-Datei eliminieren

Status: Ungelöst | Ubuntu-Version: Server 24.04 (Noble Numbat)
Antworten |

voitc

Anmeldungsdatum:
25. März 2025

Beiträge: 2

Liebe Community, ich habe bereits viele Einträge hier zu sed und auch die man-pages durch und mir gelingt es einfach nicht ☹

Ich habe eine html-Datei, in der (oft auch mehrere) Dopplungen hintereinander stehen.

Z.B. "10a, 10a, 10a, 10b, 10b, 10c, 10d"

Da möchte ich per Skript diese doppelten Einträge herauswerfen. Mein Ansatz war:

1
sed -i 's/10a\{,}\{\}10a\{,}\{\}/10a\{,}\{\}/g' test.html

ebenso mit 10b, 10c, bzw. 10d Diese würde ich dann als Schleife einfach 10-20 Mal durchlaufen lassen.

Die Datei ist aber danach unverändert. Ich tippe auf Fehler beim Komma, bzw. Leerzeichen. Habe auch schon \d044 bzw. \d032 benutzt, auch ohne Erfolg. Danke vorab an eure Hilfe!

Viele Grüße

frostschutz

Avatar von frostschutz

Anmeldungsdatum:
18. November 2010

Beiträge: 7777

Was bezwecken deine {} in diesem Kontext?

Kanns auch ein 110a, 10a oder 10a, 10ab geben? Da würde 10a, 10a ja auch drauf matchen, obwohl nicht doppelt. Deswegen ist das schwierig mit sed (korrekt) umzusetzen.

Das ist dann der Punkt, an dem du dein Glück mit awk versuchst. Oder mit python. Oder ...

Wenn du den kompletten String extrahieren kannst evtl. auch was mit uniq (arbeitet zeilenweise also müsste man Kommas ersetzen).

Mylin

Avatar von Mylin

Anmeldungsdatum:
23. Juli 2024

Beiträge: 228

1
2
3
4
5
for i in {10..20}; do
  for letter in a b c d; do
    sed -i "s/\($i$letter,\s*\)\{1,\}$i$letter/\1/g" test.html
  done
done

Dürfte mit so ziemlich jeder Kombination funktionieren.

TK87

Anmeldungsdatum:
8. Juli 2019

Beiträge: 239

Wohnort: Aachen

Moin,

das geht auch in einem Durchgang.

frostschutz schrieb:

Kanns auch ein 110a, 10a oder 10a, 10ab geben?

  • Falls nein:

    1
    2
    3
    4
    5
    6
    sed -i -E '
      s/(10a(, )?)+/\1/g;
      s/(10b(, )?)+/\1/g;
      s/(10c(, )?)+/\1/g;
      s/(10d(, )?)+/\1/g
    ' test.html
    

.

  • Falls ja: Statt sed einfach perl mit Parameter -p nutzen. Da kann man dank lookahead & lookbehind auch solche Fälle ausschließen

    1
    2
    3
    4
    5
    6
    perl -p -i -E '
      s/(?<=[> ]|^)(10a(, )?)+(?=[,< ]|$)/\1/g;
      s/(?<=[> ]|^)(10b(, )?)+(?=[,< ]|$)/\1/g;
      s/(?<=[> ]|^)(10c(, )?)+(?=[,< ]|$)/\1/g;
      s/(?<=[> ]|^)(10d(, )?)+(?=[,< ]|$)/\1/g
    ' test.html
    

Gruß Thomas

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13131

Einfache Wiederholung

1
2
3
4
$ echo "10a, 10a, 10a, 10b, 10b, 10c, 10d" | sed 's#\(10.\) *, *\1#<\1>#g'
<10a>, 10a, <10b>, 10c, 10d
$ echo "10a, 10a, 10a, 10b, 10b, 10c, 10d" | sed 's#\(10.\) *, *\1#\1#g'
10a, 10a, 10b, 10c, 10d

Mehrfache Wiederholung

1
2
3
4
$ echo "10a, 10a, 10a, 10b, 10b, 10c, 10d" | sed 's#\(10.\)\( *, *\1\)*#<\1>#g'
<10a>, <10b>, <10c>, <10d>
$ echo "10a, 10a, 10a, 10b, 10b, 10c, 10d" | sed 's#\(10.\)\( *, *\1\)*#\1#g'
10a, 10b, 10c, 10d

Die < und > dienen nur der Illustration der Ersetzung. Das Muster in der ersten Klammer muss man ggf. anpassen - je nach Bedarf.

voitc

(Themenstarter)

Anmeldungsdatum:
25. März 2025

Beiträge: 2

Vielen herzlichen Dank für die vielen schnellen Antworten. @rklm: funktioniert teilweise, immer noch Dopplungen drin, aber auch unnötige Kommata (10a, , ,).

@TK87: funktioniert gut, aber auch hier teilweise Dopplungen drin (10a, 10a, 10b, 10c). Ich habe den oberen Vorschlag ohne perl verwendet, da keine der genannten Variationen enthalten sind.

@Mylin: Dein Vorschlag enthält auch noch Dopplungen, setzt die ersetzten in eckige Klammern und ändert seltsamerweise die Spaltenbreite der Tabelle.

@frostschutz: Es war ein Versuch meinerseits mit den Leerzeichen und Kommata fertig zu werden, da mir nicht vertraut ist, wie ich die regulären Ausdrücke für diese Zeichen in einem Skript handeln muss.

Ich verfolge den Vorschlag von TK87 weiter, im Anhang ist ein anonymisierter Schnipsel der html-Datei.

test.html (4.9 KiB)
Download test.html

TK87

Anmeldungsdatum:
8. Juli 2019

Beiträge: 239

Wohnort: Aachen

rklm schrieb:

1
sed 's#\(10.\)\( *, *\1\)*#<\1>#g'

Cooler Ansatz. Ich wusste gar nicht, dass man die Gruppen auch im Suchstring schon wieder benutzen kann.

voitc schrieb:

@TK87: funktioniert gut, aber auch hier teilweise Dopplungen drin (10a, 10a, 10b, 10c).

Ist klar, in deinem Schnippsel sind ja teils auch noch CRLF enthalten. Die muss man dann im RegEx natürlich auch mitnehmen.

Ich verfolge den Vorschlag von TK87 weiter, im Anhang ist ein anonymisierter Schnipsel der html-Datei.

Sollen die 09er und 11er auch behandelt werden?

Ich mache mal einen Mix aus meinem und rklm's Vorschlag:

1
sed -zi -E 's/((09|1[01])[a-f])(,[ \r\n]*\1)+/\1/g' test.html
Antworten |