itsmee
Anmeldungsdatum: 24. März 2017
Beiträge: Zähle...
|
Hallo, ich habe input den ich gerne filtern würde:
[group1]
param1
param2
[group2]
param3
param4
[group1,group2]
param5
param6
[group1]
param7
param8 Ich finde den output etwas dusselig, kann das Format aber nicht ändern. An für sich funktionieren die gängigen Google Lösungen für das Problem - mit einer Ausnahme.
cat sections.txt | sed '/\[.*group1.*/,/\[/!d'|grep -v "^\[" |sort Und zwar wird hierbei das zweite [group1] als Pattern der ersten Sektion weggeschnitten. Damit fehlen mir aber param7 + param8 als Output - fail. cat sections.txt | sed '/\[.*group1.*/,/\[/!d'|grep -v "^\[" |sort
param1
param2
param5
param6 Freue mich über Tips ☺ ItsMee
|
misterunknown
Ehemalige
Anmeldungsdatum: 28. Oktober 2009
Beiträge: 4403
Wohnort: Sachsen
|
Du willst also die Gruppen wegfiltern? Warum dann nicht einfach folgendes:
| grep -v "^\[" sections.txt | sort
|
|
itsmee
(Themenstarter)
Anmeldungsdatum: 24. März 2017
Beiträge: 3
|
Hi, ich möchte alle Parameter einer Gruppe ausgeben. Den Gruppennamen wegfiltern ist einfach - nur die Parameter der Gruppe 1 auszugeben ist die Challenge.
Mit deiner Lösung würden auch parameter3 + 4 angezeigt. Habe mir jetzt mit einer bash loop beholfen, bin aber immer noch an einem 'coolen' Einzeiler interessiert. ItsMee
|
misterunknown
Ehemalige
Anmeldungsdatum: 28. Oktober 2009
Beiträge: 4403
Wohnort: Sachsen
|
itsmee schrieb: ich möchte alle Parameter einer Gruppe ausgeben. Den Gruppennamen wegfiltern ist einfach - nur die Parameter der Gruppe 1 auszugeben ist die Challenge.
Ah, wer lesen kann ist klar im Vorteil^^
|
misterunknown
Ehemalige
Anmeldungsdatum: 28. Oktober 2009
Beiträge: 4403
Wohnort: Sachsen
|
Ich hab einen Perl-Einzeiler geschrieben:
| perl -ne 'if(/^\[.*group1/){$p=1}elsif(/^\[/){$p=0}else{print if $p}' sections.txt
|
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Hi ItsMee, zuerst mal willkommen hier auf dem Forum ! Genau: was Du brauchst, ist ein Merker, der immer dann gesetzt wird, wenn "group1" im Block-Header vorkommt, und sonst nicht. Ich hätte genau das selbe, aber spontan eher mit awk gemacht, wie früher schon mal hier : | awk '/^\[/ {if($0~"group1") p=1; else p=0; next} p==1 {print}' sections.txt
|
aber in Perl ist es fast noch kürzer. (und ich habe gleich noch gelernt, wie Perl sowas macht !) LG, track Edit + p.s.: Es geht sogar noch etwas kürzer (und sauberer): | awk '/^\[/ {p=index($0,"group1"); next} p>0 {print}' sections.txt
|
Der einzige Knoten wäre, wenn jetzt "group1" als Teilwort in anderen Gruppen-Namen vorkäme. Dann würde er zu viel ausgeben, und man müsste wortweise genau vergleichen:
awk -F'[,\\[\\]]' '/^\[/ {for(i=1;i<=NF;i++) if(p=$i=="group1") next} p>0 {print}' sections.txt
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Die letzte Gruppe wird bei Dir nicht ausgegeben, weil die keine schließende Gruppe mehr findet.
1
2
3
4
5
6
7
8
9
10
11
12
13 | sed -n '/\[.*group1.*/,/(\[|$)/p' sections.txt
[group1]
param1
param2
[group2]
param3
param4
[group1,group2]
param5
param6
[group1]
param7
param8
|
Jetzt noch die Gruppennamen wegfiltern - sortiert ist es doch schon. Das Dollarzeichen steht manchmal, es ist überladen, für Dateiende (meist für Zeilenende oder in Verbindung mit Zahlen für zuvor gruppierte Ausdrücke).
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Mit solchen sed - Bereichen geht es grundsätzlich nicht sauber, weil dabei der nachfolgende Tag immer mit "verbraucht" wird, auch wenn er eigentlich einen neuen Block starten sollte. Beispiel: bei [group1]
param1
param2
[group1]
param1a
param2a
[group2]
param3
param4
[group1,group2]
param5
param6
[group1]
param7
param8 fehlen genau aus diesenm Grund param1a, param2a, param7, param8 : (n.b.: das ist schon die korrigierte Version, die das Ende berücksichtigt und die Tags wegfiltert !) track@track:~$ cat sections2.txt <(echo \[) | sed -n '/\[.*group1.*/,/^\[/ {/^[^\[]/ p}'
param1
param2
param5
param6 Auch bei sed braucht man für eine saubere Lösung einen "Merker". Der besteht dabei aber nicht aus einer Variablen (weil es die dort nicht gibt !), sondern aus einer Schleife, in die er nach dem gesuchten Block-Tag einsteigt: track@track:~$ sed -n '/^\[.*group1.*/ { :a n; /^[^\[]/{p; ba}; /^\[.*group1.*/ ba}' sections2.txt
param1
param2
param1a
param2a
param5
param6
param7
param8 Der Befehl sieht etwas verzwickt aus, und ist es auch. (Das mag genügen. Bei Interesse reiche ich ggf. den Erklärbär nach.) Deshalb empfehlen sich eigentlich nur die Lösungen mit Perl oder awk : die sind straighter und übersichtlicher. LG, track
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
track schrieb: Mit solchen sed - Bereichen geht es grundsätzlich nicht sauber, weil dabei der nachfolgende Tag immer mit "verbraucht" wird, auch wenn er eigentlich einen neuen Block starten sollte.
Ich habe mich schon gewundert, wieso es dann bei mir geklappt hat. Hatte mich schon gefragt, als ich den Sedbefehl hintippte, ob das klappen kann - genau aus dem Grunde, und dann einen dummen Doppelfehler produziert, bzw. 3-Fachfehler: Erstens wurde mein $-Zeichen gar nicht als Dateiendezeichen gewertet, zweitens habe ich den Schalter -r vergessen, der aus dem Ausdruck (\[|$) eine Gruppe gemacht hätte und dann habe ich noch bei der Kontrolle übersehen, dass mir die zweite Sektion, die unterdrückt werden sollte, gar nicht unterdrückt wurde und den ganzen Ausdruck deswegen fälschlich, wenn auch überrascht als gelungen geschluckt. Wie peinlich! Da ich hinter diese Schleifen mit sed nie wirklich hintergestiegen bin empfehle ich jetzt auch sonst niemandem sed für diese Aufgabe, außer track, der es offenbar gemeistert, aber auch andere Vorlieben hat. ☺
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
user_unknown schrieb: Da ich hinter diese Schleifen mit sed nie wirklich hintergestiegen bin ...
Ist nicht wirklich kompliziert, sondern genau so platt und primitiv wie Schleifen bei BASIC : GOTO + Sprungziel, das ist alles. (nur, bei sed typischerweise mit Befehlskürzeln) .. empfehle ich jetzt auch sonst niemandem sed für diese Aufgabe
Yep, hast Du Recht: muss wirklich nicht sein. .. außer track, der es offenbar gemeistert, aber auch andere Vorlieben hat. ☺
Oooch, nachdem ich zuerst die prinzipiellen Dinge geklärt hatte, wollte ich es einfach wissen, und habe mich da etwas ausgetobt ... Aber wie gesagt: das Entscheidende war, dass ich zuerst mal für mich geklärt habe, was wichtig und was sinnvoll ist ! (sonst artet sowas nämlich in planloses Probieren aus) LG, track
|
itsmee
(Themenstarter)
Anmeldungsdatum: 24. März 2017
Beiträge: 3
|
Hi, danke Euch für die intensive Diskussion - hilfreich. Im Endeffekt habe ich das Gleiche (Marker) wie Ihr in AWK / Perl mit Bash gemacht.
Und wenn ich das jetzt vergleiche wird es höchste Zeit wieder mal ein perl projekt zu suchen, 4-5 Jahre nix mit gemacht & schon ist die Einstiegshürde (a.k. Faulheit) zu gross gewesen. Grüße & Danke, ItsMee
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12822
|
itsmee schrieb:
Und wenn ich das jetzt vergleiche wird es höchste Zeit wieder mal ein perl projekt zu suchen, 4-5 Jahre nix mit gemacht & schon ist die Einstiegshürde (a.k. Faulheit) zu gross gewesen.
Dann nimm lieber Ruby - das macht viel mehr Spaß als Perl. 😉
|