Aus Dateien was "rausschneiden"

J

Janine

Eroberer
Hallo Jungs,

ich hab eine "configfile"

z.B.

[x]
abc=1
bac=2
cba=3

[y]
abc=2
bac=1
cba=3

[z]
...
...
...


So also dieses File ist in Abschnitte unterteilt die immer mit "[]"

gekennzeichnet sind und ich möchte jetzt wissen wie ich aus der ganzen Datei

immer nur einen Abschnitt z.B. den Abschnitt "[x]" mit allen Werten darunter bis Abschnitt [y] rausschneide und in einem anderen File abspeicher so das es in dem anderen File nur das gäbe...

[x]
abc=1
bac=2
cba=3
 
Zuletzt bearbeitet:
Also ich kenn mich zwar nich wirklich mit shellscripten aus aber such doch einfahc nach z.B. "[x]" und sag er soll die darauffolgenden zeilen solange in die andere datei speichern bis er "[y]" findet bzw nur eine "["
 
Versuch doch mal:
Code:
csplit -k conf '/^\[.*\]$/' {99}
wenn nicht mehr als 99 solcher Abschnitte in der conf-Datei enthalten sind ...

Grüße
 
hmmm da macht er mir das selbe in diese xx00 Datei wies auch in der echten datei steht will ja nur z.b den ersten Abschnitt unter "[x]" in der datei haben
 
Hallo

Wenn es ohne [x] sein soll, also nur die Zeilen zwischen [x] und [y] hilf ein sed mit Label eventuell weiter.
Code:
$ cat test
[x]
abc=1
bac=2
cba=3
[y]
abc=2
bac=1
cba=3
[z]
$ sed -ne ':loop /\[x\]/d;N;/\[y\]/!b loop;/\[y\]/s/\n\[y\]//g;p' test
abc=1
bac=2
cba=3

Soll es mit dem [x] sein, einfach das d weglassen:

Code:
sed -ne ':loop /\[x\]/N;/\[y\]/!b loop;/\[y\]/s/\n\[y\]//g;p;q' test

Gruß Wolfgang
 
Zuletzt bearbeitet:
also iwie ist das noch nicht ganz das was ich suche auch weil schon wenn man

[z]
abc=1
bac=2
cba=3
[x]
abc=2
bac=1
cba=3
[y]
...
...
...


das jetzt so rum hat findet er zb gar nix also das net so gut ^^


kann man das ganze nicht auch iwie mit grep machen?

Weil ich brauch das ganze auch variable das heisst die packete stehen in den beiden config files nicht immer an der selben stelle.
 
Zuletzt bearbeitet:
Code:
sed -n '/^\[x\]$/,/^\[.\]$/{N;p}' foo.txt
 
Zuletzt bearbeitet:
Das wolltest du nicht?

Code:
stephan@unimatrix ~ :) $ cat foo.txt 
[z]
abc=1
bac=2
cba=3
[x]
abc=2
bac=1
cba=3
[y]
stephan@unimatrix ~ :) $ sed -n '/^\[x\]$/,/^\[.\]$/{N;p}' foo.txt
[x]
abc=2
bac=1
cba=3
stephan@unimatrix ~ :) $

Wenn nein, dann verzähl mal. :)
 
Also ich will das das ganze auch klappt wenn die Options wie z.B. [x] nicht in der mitte steht sondern am anfang oder was weiss ich an was für ener stelle :)

dein sed klappt jetzt z.B. nur wenn die Pakete in der Reihenfolge [z][x][y] stehen aber nicht wenn sie [x][y][z] z.B. stehen selbe Prob wie bei dem Herrn drüber ^^

Ich versuch nochmal neu zu Formulieren was genau ich haben will.

Und zwar hab ich 2 Files die ich miteinander vergleichen muss

File 1

[x]
abc=1
bac=2
cba=3
[y]
abc=2
bac=1
cba=3

File2

[y]
abc=1
bac=2
cba=3
[x]
abc=2
bac=1
cba=3


hab jetzt mal nur 2 Packete in den Files gemacht (die Pakete können im file 2 an einer anderen stelle stehen als in file1)

so und ich will die files vergleichen und dafür muss ich die einzelenen Packete vom file1 und file2 jeweils immer die selben aus den files rausschneiden und zb in puffer1 und puffer2 abspeichern weil dann kann ich die in den dateien sortieren mit sort und dann mit compare vergleichen :)

So und dann immer so weiter file1 ist praktisch der boss und gibt an welches packet als nächstes ausgeschnitten wird, und dann muss halt im file 2 wieder nach diesem abschnitt gesucht werden.

iwie komplizierte scheisse und ich als neuling kack da gerade mal voll drauf ab :(




ps: jetzt sag mir nicht warum ich nicht direkt nen sort mache und dann comm vergleich.... :P geht ja nicht weil manche Variablen in mehreren Packeten auftreten können und dann funzt das ganze so z.B. nicht ^^ deswegen diese kacka mit dem Packete rausschneiden :(
 
Zuletzt bearbeitet:
Hallo
@Janine

Wenn du Hilfe erwartest, musst du schon genaue eindeutige Ausgangsbedingungen festlegen und das Ergebnis klar definieren.

Der Vorschlag von mir ging davon aus, dass du einen Bereich zwischen einem einführenden [x] und abschließendem [y] willst. Wobei mein Vorschlag das [y] nebst nachfolgendem Leerzeichen abschneidet. Dabei sind vorgestellte Leerzeichen oder nachfolgende Leerzeichen beim [x] und [y] egal.

Code:
$ cat test
[z]
abc=1
bac=2
cba=3
[x]
abc=2
bac=1
cba=3
[y]
abc=3
bca=2
cba=1
[a]

wolle@Nietzsche:/tmp
$ sed -ne ':loop /\[x\]/d;N;/\[y\]/!b loop;/\[y\]/s/\n\[y\]//g;p' test
abc=2
bac=1
cba=3
wolle@Nietzsche:/tmp

Wenn du nun alles nach dem [x] bis zur nächsten Klammer (ohne diese selbst ) willst, egal ob dort [y] oder [.] steht.

Code:
$ cat test
[z]
abc=1
bac=2
cba=3
[x]
abc=2
bac=1
cba=3
[w]
abc=3
bca=2
cba=1
[y]

wolle@Nietzsche:/tmp
$ sed -ne '/\[x\]/b l;d;:l N;/\[[^x]\]/!b l;s/\n[[:space:]]*\[[^x]\].*$//g;p;' test
[x]
abc=2
bac=1
cba=3
wolle@Nietzsche:/tmp

PS wenn man einen Bereich addressiert wie bei @smg seinen Vorschlag, wird dieser komplett mit Beginn und Ende ausgegeben.
Deshalb verwende ich hier ein label.

Kurze erklärung:
Erst prüfe ich, ob [x] erreicht ist. wenn nicht löschen und nächste Zeile, sonst springe zu Label l
Code:
/\[x\]/b l;d;
Jetzt kommt das Label (hier l)
Das holt neue Zeile und hängt diese an den Patternspace an, prüft auf [(NICHT x)]. Wenn zutreffend wieder zu Label springen , was wieder neue Zeile holt prüft usw...

Code:
:l N;/\[[^x]\]/!b l;

Wenn [ mit irgend einem Zeichen ungleich x kommt, springe ich nicht mehr und komme zum letzten Teil. Dieser löscht Newline gefolgt von eckiger Klammer mit Zeichen ungleich x bis zum Ende und gibt alles aus. Dadurch erscheint keine abschließende Leerzeile.
Das [[:space:]]* ist nötig, falls Leerzeichen vor der Klammer vorkommen können.
Ist das nicht der Fall, kannst du das weglassen.
Code:
s/\n[[:space:]]*\[[^x]\].*$//g;p;'

Hoffe alles ist klar.
Gruß Wolfgang (der eigentlich im Urlaub ist)
 
oh man Wolle dann genieß den urlaub :) aber riesen grosses dankeschön das du dir soviel mühe gegeben hast und zeit mir das zu erklären, echt super nett von dir.
 
Naja also jetzt klappt das schonmal ganz gut mit den Parametern nur kann ich da ja jeweils immer nur einen bestimmten Bereich angeben mit

sed -ne '/\[$1\]/b l;d;:l N;/\[[^$1]\]/!b l;s/\n*\[[^$1]\].*$//g;p;' test



Aber hat jemand eine idee wie ich das ganze jetzt so machen kann das er alle packete durchgeht nacheinander?

Also im ersten File die pakete nacheinander abarbeitet und dann praktisch mit dem paketnamen das selbige in datei 2 findet ?

Und dann halt so alle pakete durchgeht.


Wird ja wohl iwas mit einer do while schleife sein wenn ich mich nicht irre.

Grosse Frage ist wie ich beim zweiten sed für file 2 jeweils immer das gleiche packet rauskriege wie es in File 1 am nächsten dran ist müsste ne variable sein.

Und vorallem mach ich es atm so das ich die 2 packete immer in 2 verschieden puffer files packe die mit diff vergleiche und dann wieder remove die pufferfiles
 
Zuletzt bearbeitet:
Hallo
Falls du aus zwei Dateien die Blöcke suchst, die in beiden gleich vorkommen, habe ich einen schnellen dirty Perl-Hack.
Einzige Bedingung, die Dateien müssen am Ende mit einer Leerzeile enden.
Das Ende eines Blockes zu erkennen ist am Dateiende nicht so trivial wie es scheint.
Ist sicher verbesserungswürdig, aber funktioniert hier.
Code:
$ cat test
[x]
abc=1
bac=2
cba=3
[y]
abc=2
bac=1
cba=3
[z]
abc=2
bac=3
cba=1

wolle@Nietzsche:/tmp
$ cat test1
[x]
abc=1
bac=2
cba=3
[y]
abc=2
bac=1
cba=3
[z]
abc=3
bac=3
cba=3
[w]
abc=1
cba=3
bca=2

wolle@Nietzsche:/tmp
$ perl  -anle 'if((/(\[[a-z]\])/)||(/^\s*$/)){($i)?$h{$i}.=@ARGV:1;$i="$_"}else{$i.="\n$_"}END{($h{$_}=~/^10$/)?print $_:1 for keys %h}' test test1
[y]
abc=2
bac=1
cba=3
[x]
abc=1
bac=2
cba=3

Naja, eventuell ist es ja etwas Anderes, was du suchst.
Aber ich bin im Urlaub und überlass das dann mal den Anderen.
BTW Wenn du eine Shellvariable in sed einfügen willst, verwende doppelte Hochkomma, statt einfachen.
Code:
var=bar;
sed -e "s/$var/foobar/g"  file

Gruß Wolfgang
 
Also das klappt wunderbar wenn ich mit meiner Beispeil config das test wo die abschnitte nur mit jeweils einem buchstaben sind wie [a] [c]

aber sobald ich versuche es mit einer richtigen config zu machen wo die einzelnen abschnitte halt richtig benannt sind mit [general] [log] [option] usw also mehr als nur 1 buchstabe in den [] dann klappt das schon nicht mehr richtig mit dem hier

sed -ne "/\[$1\]/b l;d;:l N;/\[[^$1]\]/!b l;s/\n\[[^$1]\].*$//g;p;" $2 >> puf



versteh aber nicht warum da er doch eigentlich richtig matchen müsste...

$1 wird halt der abschnitt angegeben z.B. option und $2 ist die datei

naja maybe entdeckt ihr ja einen fehler in dem sed warum es mit 1 buchstaben klappt aber nicht richtig matcht auf komplette wörter
 
Hallo

Bei der Verwendung von Shellvariablen (also mit doppelten Hochkomma) macht dir das ! einen Strich durch die Rechnung, weil es von der bash als History interpretiert wird.
Das musst du also ausschließen.
Ich verwende hier mal $a statt $1
Code:
$ cat test
[foo]
abc=1
bac=2
cba=3
[bar]
abc=2
bac=1
cba=3
[z]
abc=3
bac=3
cba=3
[w]
abc=1
cba=3
bca=2
wolle@Nietzsche:~
$a=bar
wolle@Nietzsche:~
$ sed -ne "/\[$a\]/b l;d;:l N;/\[[^$a]\]/"'!'"b l;s/\n\[.*$//g;p;" test
[bar]
abc=2
bac=1
cba=3

Gruß Wolfgang
 
Zuletzt bearbeitet:
Oh man ich würde dich glatt heiraten xD vielen vielen dank :)
 
Glaub mir, das lohn sich nicht.

nana.. nicht so bescheiden! Wenn du kein Kaffee kochen kannst musst du eben den Müll raus bringen und derartige Aufgaben erledigen! Eben klare Rollenverteilung und so :D

:bounce: @Janine: Heiratsanträge übers Forum sind ja auch mal was nettes :bounce:
 
nana.. nicht so bescheiden! Wenn du kein Kaffee kochen kannst musst du eben den Müll raus bringen und derartige Aufgaben erledigen! Eben klare Rollenverteilung und so :D

:bounce: @Janine: Heiratsanträge übers Forum sind ja auch mal was nettes :bounce:

Sollten wir dafür ein Subforum eröffnen? "Heiratsansträge"? :)
Kaffee muss man nicht kochen, dafür gibt's super Kaffeevollautomaten! :)
 

Ähnliche Themen

Zeilen behalten, die Werte in einem bestimmten Bereich enthalten

Spalten einer Datei in neue Datei integrieren.

Python Script Hilfe

Keine grafische Oberfläche (Debian Installation)

[Gelöst] Suchen und ersetzen mit Hilfe mehrerer Parameter

Zurück
Oben