estrela
Goto Top

Kombinieren von Zeilen mit Linux-Shell

Hallo.

Ich möchte mit einem Linux-Shell-Skript folgende Aufgabe lösen.

In einer Datei parameter stehen zeilenweise einzelne Parameter.

Diese sollen alle miteinander kombiniert und zeilenweise in die Datei kombi geschrieben werden.

Die Datei mit den Parametern kann man sich als zeilenweise Liste von Parameter 1 - z.B 100 vorstellen.
Also eine belibige Anzahl von Parametern stehen zeilenweise in der Datei parameter ( als Buchstaben/ Zahlenkombination).

Diese zeilenweise stehenden Parameter sollen jetzt alle miteinander im ersten Schritt pärchenweise kombiniert und durch ":" getrennt werden, um alle 2er Kombinationen zu bilden, wobei jede Kombination in eine Zeile der Datei kombi geschrieben werden soll, wobei die Zeilen schematisch bei den 2er Kombinationen dann alle z.B. so aussehen:
para18:para99
wobei hier im Beispiel para18 usw als Platzhalter für die tatsächlichen Werte zu verstehen ist.

Im nächsten Schritt werden aus der Datei parameter wieder alle Inhalte der Zeilen kombiniert, diesmal als 3er Gruppen, also z:B.:
para1:para21:para99

Grundsätzlich sollen also auf jeder Kombinationsebene alle Inhalte der Zeilen der Datei parameter miteinander kombiniert und Zeilenweise in die Datei kombi durch ":" getrennt geschrieben werden.

Optimal ist eine Lösung, bei der ich mit Aufruf des Scripts eine Zahl angeben kann, die als maximale Kombinationstiefe ( also wieviele Parameter maximal in einer Zeile stehen, weil die entsprechenden Gruppen gebildet wurden) ins Programm einfliest.

Also "scriptname 4" bedeutet, das die 2er, 3er und 4er Gruppen gebildet werden sollen.

Alternativ währe auch eine Änderung der Kombinationstiefe über das Editieren einer Variablen.

Da ich im Programmieren nicht so fit bin, möchte ich hier mal nachfragen, ob jemand eine Lösung kennt und zeigt.

Gruß

Estrela

Content-Key: 138164

Url: https://administrator.de/contentid/138164

Printed on: April 19, 2024 at 04:04 o'clock

Member: Korrn
Korrn Mar 13, 2010 at 21:55:06 (UTC)
Goto Top
Mahlzeit,

Inputdateiname: paras
Outputdateiname: paras.out

#!/bin/bash

depth=2
infile="paras"  
outfile="paras.out"  

parout=""  
parnum=0


if [ "$#" == "1" ]  
then
	depth=$1
fi


while read line
do
	if [ "$parnum" == "$depth" ]  
	then
		parnum=0
		echo "${parout:1}" >> $outfile  
		parout=""  
	fi

	parout="${parout}:${line}"  
	
	((parnum+=1))

done < $infile

exit 0
Member: Estrela
Estrela Mar 13, 2010 at 23:25:19 (UTC)
Goto Top
Hallo Korrn.

Super, danke Dir für Deine Antwort.

Das mit der Kombinationstiefe funktioniert schon einwandfrei.

Nur, wenn ich in der Ausgangsdatei 12 Begriffe stehen habe und jeder mit jedem kombiniert wird, ergibt das bei 2er Gruppen ca. 144 Kombinationen.
In der Ergebnisdatei stehen aber nur drei Zeilen, in der die ersten 9 Begriffe der Ausgangsdatei als 3er ( nach Editierung von depth) Gruppen zeilenweise stehen, die letzten 3 Zeilen der Ausgangsdatei bleiben unberücksichtigt.

Das bedeutet also, das alles funktioniert bis auf das Kombinieren. Gültige Kombinationen sind auch Wiederholung an unterschiedlicher Stelle, also:
para1:para33:para44
para1:para44:para33
para33:para44:para1
usw
sind alles gültige und gewünschte Kombinationen.
Also die Einzigartigkeit bezieht sich auf die Zeile und nicht darauf, das ein Parameter der Ausgangsdatei nur einmal im Ergebnis auftauchen darf.

Währe super, wenn Du das noch mit einbauen kannst.

Danke soweit

und ein schönes Restwochenende

Estrela
Member: Korrn
Korrn Mar 14, 2010 at 18:35:20 (UTC)
Goto Top
Hi,

sorry falsch verstanden.

Jetzt auch mit dem gewünschten Ausgabe-Datei-Namen, und Vorsicht: falls die Paras-Datei eine Leerzeile (z.B. am Ende) beinhaltet, wird diese mit verarbeitet.

Voilá:
#!/bin/bash

maxdepth=2
depth=0
tempfile=$(mktemp)
infile="paras"  
outfile="kombi"  
counter=1
parout=""  

if [ "$#" == "1" ]  
then
	maxdepth=$1
fi

cp -v $infile $tempfile


while [[ $counter -lt $maxdepth ]]
do
	((counter+=1))
	while read lines
	do
		while read linet
		do
			echo "${linet}:${lines}" >> $outfile  

		done < $tempfile
	done < $infile	

	cp $outfile $tempfile

done

rm $tempfile

exit 0

Grüße
Member: Fraenky
Fraenky Mar 15, 2010 at 13:46:08 (UTC)
Goto Top
Funktioniert.
Member: Estrela
Estrela Mar 15, 2010 at 14:16:55 (UTC)
Goto Top
Hallo Korrn.

Funktioniert fast alles wunderbar. Danke Dir dafür.

Nur habe ich eine ungewünschte Auffälligkeit entdeckt.

In der Ergebnisdatei steht auch folgendes:

para1:para1

sowie in 3er Gruppen

para4:para2:para2

Das sollte nicht geschehen, das ein Parameter doppelt in einer Zeile steht.

Kannst Du nicht noch vor dem Schreiben in die Ergebnisdatei mit einem regulären Ausdruck überprüfen, ob ein Parameter mindestens doppelt in der zu schreibenden Zeile vorkommt und
falls ja, die Zeile nicht in Ergebnisdatei schreiben.

Das währe dann very perfect.

Danke auch für Deine Hinweise

und alles Gute wünscht

Estrela
Member: Korrn
Korrn Mar 15, 2010 at 21:24:11 (UTC)
Goto Top
Tach,

aller guten Dinge sind drei:
#!/bin/bash

maxdepth=2
depth=0
tempfile=$(mktemp)
tempfile2=$(mktemp)
infile="paras"  
outfile="kombi"  
counter=1
parout=""  
parnum=0

> $outfile

if [ "$#" == "1" ]  
then
	maxdepth=$1
fi

cp $infile $tempfile


while [[ $counter -lt $maxdepth ]]
do
	((counter+=1))
	while read lines
	do
		while read linet
		do
			echo "${linet}:${lines}" >> $outfile  

		done < $tempfile
	done < $infile	

	cp $outfile $tempfile

done


while read line
do
	cp $tempfile $tempfile2
	> $tempfile
	grep -v "${line}:${line}" $tempfile2 >> $tempfile  
done < $infile

cp $tempfile $outfile 

rm $tempfile
rm $tempfile2

exit 0

Jetzt werden alle Zeilen mit "para1:para1" rausgefiltert. Oder sollen auch Zeilen mit "para1:paraX:para1" rausgefiltert werden?
Stören die Zeilen, in denen nicht die maximale Iterationstiefe erreicht wird?

Gute Nacht, bis morgen face-wink
Member: Estrela
Estrela Mar 16, 2010 at 12:41:45 (UTC)
Goto Top
Hallo Korrn.

Funktioniert wieder alles bis auf die von Dir angesprochenen Umstände.
Ein Parameter darf nicht 2x in einer Zeile auftauchen. Ist egal, ob er direkt nacheinander oder durch andere Parameter getrennt doppelt auftaucht. Das kann man als Regel so einführen.

Die Zeilen, die nicht die maximale Kombinationstiefe erreichen, dürften wohl die Restzeilen sein und werden dadurch währscheinlich schon von den anderen Kombinationsgruppen kleinerer Größe abgebildet, so das wahrscheinlich eine Doppelung vorliegt und daher die Zeilen nicht auftauchen müssen.

Weiter viel mir bei einem nachträglichen Versuch, die Ergebnisdatei zu sortieren, auf, das bei einer Sortierung durch sort der Gruppenzusammenhang verlohren geht, das bedeutet, das 2er und 3er Gruppen gemischt sortiert werden.
Gut, dem könnte man durch vorherige Trennung der Gruppen mit anschließender seperierter Sortierung begegnen, aber optimal währe sicherlich ein Script, das dieses Vorgehen schon implementiert hat, also zuerst die kleinste Gruppe sortieren, danach die nächsthöhere usw.

Aber wie gesagt, das letztere währe ein Feinschliff, der auch händisch zu umgehen ist, wobei die Vermeidung irgendeiner Dopplung eines Parameters in einer Zeile schon als wichtiger zu betrachten ist.

Nochmal herzlichen Dank

und Gruß

Estrela