staging.inyokaproject.org

SED insert only once

Status: Ungelöst | Ubuntu-Version: Ubuntu 18.04 (Bionic Beaver)
Antworten |

linzus

Anmeldungsdatum:
31. Dezember 2015

Beiträge: 147

Hi,

ich möchte mit SED innerhalb einer File vor dem ersten Auftreten eines Strings einen weitren einfügen, allerdings nur einmalig.

Mein Kommando hierfür ist:

1
sed -ie "/@\t*IN\t*TXT\t*/i $full_record" my_zone.file

Leider fügt dieser Befehl den full_record vor jedem Auftreten eines TXT-RR ein, ich möchte dies aber nur einmalig.

Hat jemand einen Tipp?

VG

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 10978

Mit GNU sed (was bei Ubuntu standardmäßig dabei ist) sollte sowas möglich sein:

1
sed -ie "0,/@\t*IN\t*TXT\t*/i $full_record" my_zone.file

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 12527

seahawk1986 schrieb:

Mit GNU sed (was bei Ubuntu standardmäßig dabei ist) sollte sowas möglich sein:

1
sed -ie "0,/@\t*IN\t*TXT\t*/i $full_record" my_zone.file

Achtung, das funktioniert nicht ganz wie beabsichtigt. Du musst die Option "-e" abtrennen, weil es in dieser Form der Backup-Suffix ist. Da "-e" aber sowieso optional ist, macht das hier keinen Unterschied. Nur, dass es halt ein Backup gibt, das ein "e" hinten am Namen hat. ☺

linzus

(Themenstarter)

Anmeldungsdatum:
31. Dezember 2015

Beiträge: 147

Hallo seahawk1986 & rklm,

vielen Dank für eure Tipps, leider hat weder

1
sed -ie "0,/@\t*IN\t*TXT\t*/i $full_record" my_zone.file

noch

1
sed -i "0,/@\t*IN\t*TXT\t*/i $full_record" my_zone.file

geholfen. Ich bekomme auch weiterhin alle gefundenen Einträge appended, anstatt nur den ersten.

VG

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 12527

linzus schrieb:

vielen Dank für eure Tipps, leider hat weder [...] geholfen. Ich bekomme auch weiterhin alle gefundenen Einträge appended, anstatt nur den ersten.

Ich glaube, das ist mit sed sehr mühsam, denn Du musst Dir den Zustand merken, dass Du schon einen Fund hattest. Ich vermute, man muss dafür nach dem ersten Fund an ein Label springen und von da den Rest der Eingabe manuell lesen und ausgeben. Wenn ich am WE Zeit habe, dann versuche ich das vielleicht mal.

Ich würde das eher mit awk machen:

1
awk -v "rec=$full_record" 'rec && /@\t*IN\t*TXT/ {print rec; rec=""} {print}' my_zone.file

Man muss dann natürlich noch die Ausgabe auffangen und auf die ursprüngliche Stelle schieben:

1
awk -v "rec=$full_record" 'rec && /@\t*IN\t*TXT/ {print rec; rec=""} {print}' my_zone.file >| my_zone.file.tmp && mv -f my_zone.file.tmp my_zone.file

Die Suche nach "\t*" am Ende ist übrigens zwecklos. Das kann man sich sparen, weil die Sequenz auch den Leerstring erkennt und damit passt, egal was hinter "TXT" kommt.

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 10978

linzus schrieb:

Hallo seahawk1986 & rklm,

vielen Dank für eure Tipps, leider hat weder

1
sed -ie "0,/@\t*IN\t*TXT\t*/i $full_record" my_zone.file

noch

1
sed -i "0,/@\t*IN\t*TXT\t*/i $full_record" my_zone.file

geholfen. Ich bekomme auch weiterhin alle gefundenen Einträge appended, anstatt nur den ersten.

Wie sieht denn so eine Zeile in der Datei aus, auf die er matchen soll? Wenn die * als Marker für beliebig viele \t gedacht sind, sollte es eigentlich klappen:

$ cat test.file 
@	IN	TXT	
foo
@	IN	TXT	
foo
 sed '0,/@\t*IN\t*TXT\t*/i [spam]' test.file 
[spam]
@	IN	TXT	
foo
@	IN	TXT	
foo 

Falls die * in der Datei stehen, müsste man sie im sed-Befehl escapen.

dingsbums

Anmeldungsdatum:
13. November 2010

Beiträge: 3337

Wäre nicht Folgendes denkbar:

  • Datei1 zeilenweise einlesen

  • Wird der Suchtext nicht gefunden, die Zeile in Datei2 schreiben

  • Wird der Suchtext gefunden, den gewünschten Zusatztext in Datei2 schreiben (Suchtext=Zeile) oder die Ersetzung per sed ohne "global" (Suchtext Teil von Zeile)

  • die restlichen Zeilen nach Datei2 durchreichen

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 12527

dingsbums schrieb:

Wäre nicht Folgendes denkbar:

  • Datei1 zeilenweise einlesen

  • Wird der Suchtext nicht gefunden, die Zeile in Datei2 schreiben

  • Wird der Suchtext gefunden, den gewünschten Zusatztext in Datei2 schreiben (Suchtext=Zeile) oder die Ersetzung per sed ohne "global" (Suchtext Teil von Zeile)

  • die restlichen Zeilen nach Datei2 durchreichen

Das ist ja das, was das awk-Skript macht.

dingsbums

Anmeldungsdatum:
13. November 2010

Beiträge: 3337

linzus schrieb:

ich möchte mit SED innerhalb einer File vor dem ersten Auftreten eines Strings einen weitren einfügen, allerdings nur einmalig.

Eigentlich erfüllt doch ein einfaches

sed 's#SUCHTEXT#ZUSATZ+SUCHTEXT#'

diese Anforderung?

1
2
echo "man muss nur üben, üben und nochmals üben" | sed 's#üben#sehr viel üben#'
man muss nur sehr viel üben, üben und nochmals üben

Oder verstehe ich die Original-Anforderung falsch?

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 12527

dingsbums schrieb:

linzus schrieb:

ich möchte mit SED innerhalb einer File vor dem ersten Auftreten eines Strings einen weitren einfügen, allerdings nur einmalig.

Eigentlich erfüllt doch ein einfaches

sed 's#SUCHTEXT#ZUSATZ+SUCHTEXT#'

diese Anforderung?

Nein, weil nur das erste Vorkommen zur Ersetzung bzw. Einfügung führen soll.

Oder verstehe ich die Original-Anforderung falsch?

Es hat den Anschein.

dingsbums

Anmeldungsdatum:
13. November 2010

Beiträge: 3337

Tut es doch in meinem Beispiel. Nur das erste "üben" wird ersetzt.

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 10978

Aber in jeder Zeile, in der es vorkommt...

dingsbums

Anmeldungsdatum:
13. November 2010

Beiträge: 3337

Stimmt, da war ich auf dem Holzweg. Das "global" oder "nicht global" bei sed bezieht sich auf die Zeile, nicht auf die Datei.

Antworten |