bash: Doppelte Einträge aus 2 Strings herausfiltern

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
FreakyFrank
Beiträge: 28
Registriert: 12.10.2004 15:12:41

bash: Doppelte Einträge aus 2 Strings herausfiltern

Beitrag von FreakyFrank » 20.12.2004 10:52:46

Hallo,
ich habe ein Shellskript mit 2 listen von versch. Verzeichnissen jeweils in einer variable. Ich möchte diese 2 Listen nun vergleichen und die doppelten Einträge herausfiltern.
Für Dateien gibt es ja da schon zig Befehle wie comm, diff oder uniq.
Aber wie kann ich sowas bei Variablen lösen?

Gruß

Frank

Benutzeravatar
Joghurt
Beiträge: 5244
Registriert: 30.01.2003 15:27:31
Wohnort: Hamburg
Kontaktdaten:

Beitrag von Joghurt » 20.12.2004 11:51:55

Schreib sie doch einfach in eine temporäre Datei, oder löse es mit pipes...

Code: Alles auswählen

echo $VAR1|sort -u

Benutzeravatar
FreakyFrank
Beiträge: 28
Registriert: 12.10.2004 15:12:41

Beitrag von FreakyFrank » 20.12.2004 14:40:16

Hab jetzt mal halbwegs ne Lösung gefunden

Code: Alles auswählen

#!/bin/sh
var1="1 2 3 4 5 6 7 8 9 10"
var2="2 3 10"
var1=`echo $var1 | sed -e  "s/ /\n/g"`
var2=`echo $var2 | sed -e "s/ /\n/g"`
echo  $var1
echo  $var2

for liste in $var2 
do
             echo "Argument $liste"
             var1=`echo $var1 | sed -e "s/ /\n/g" -e "s/\<"$liste"\>//g" -e "/^ /d"`
             #-e "/\<"$liste"\>/d"`
done

echo "Sedtest="; echo "$var1" 
Aber 2 Dinge die mich wundern:
Warum werden $var[1,2] beim echo (Zeile 6) trotz sed in einer Linie dargestellt? Die Letzte Ausgabe stellt $var1 ja auch mit Newline dar. Komischer weise funktioniert das ersetzten der Zahlen in $var2 durch leerzeichen und dann deren löschen per "/^ /d" aber nicht das Löschen der kompletten Zeile (Siehe Zeile 13) . Die Anführungszeichen sind doch richtig gesetzt? Weil bei dem Ersetzten Befehl gehts ja auch so.

Gruß

Frank

Benutzeravatar
Joghurt
Beiträge: 5244
Registriert: 30.01.2003 15:27:31
Wohnort: Hamburg
Kontaktdaten:

Beitrag von Joghurt » 20.12.2004 14:55:07

Warum ersetzt du die Leerzeichen durch Newlines? For blabla in ...; beachtet den IFS:
man bash hat geschrieben:IFS The Internal Field Separator that is used for word splitting after expansion and to split lines into words with the read builtin command. The default value is ``<space><tab><new-line>''.
Das ganze sed-Gedöhns ist also eigentlich unnötig

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 20.12.2004 15:00:28

was hast du eigentlich gegen die Lösung von Joghurt ?

Code: Alles auswählen

#!/bin/sh
var1="1 2 3 4 5 6 7 8 9 10"
var2="3 4 10 13"
var3=`echo $var1 $var2 | sed -e "s/ /\n/g" | sort -u`
echo $var3

Benutzeravatar
Joghurt
Beiträge: 5244
Registriert: 30.01.2003 15:27:31
Wohnort: Hamburg
Kontaktdaten:

Beitrag von Joghurt » 20.12.2004 15:04:44

gms hat geschrieben:was hast du eigentlich gegen die Lösung von Joghurt?
Kaninchen (und wohl auch Hasen) können keinen Milchzucker verdauen, und vertragen deshalb keinen Joghurt.

Vielleicht deshalb :twisted:

Benutzeravatar
FreakyFrank
Beiträge: 28
Registriert: 12.10.2004 15:12:41

Beitrag von FreakyFrank » 20.12.2004 17:06:53

1. Die newlines deswegen, weil im richtigem skript var1 von find die directorys liest. Und die Ausgabe ist ja untereinander. Var2 liest von $* welche ja mit leerzeichen in der variable stehen. Um das auf gemeinsamen nenner zu bringen muß ich wohl seden. Und warum nicht gleich auch die Schnittmenge mit sed rausschneiden.
2. Newlines, weil sed öfters im skript mal noch mit $var2 zu tun bekommt.
3. Es bleibt doch jeden überlassen seine Programme so zu schreiben wie er es will.
4. Ich habe nix gegen die Lösung von Joghurt. Fand es nett daß er mir den Tipp gegeben hat, und danke Ihm hiermit auch.

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 20.12.2004 18:11:24

Sicher bleibt es jedem überlassen seine Programme so zu schreiben wie er es will.
Du kannst ja deine newlines in das folgende Script nachträglich einbauen. Notwendig ist das aber nicht.

dieses Script

Code: Alles auswählen

#!/bin/sh 
touch 1 2 3 4 5 6 7 8 9 10
var1=`find -name "[0-9]*" -printf "%f\n"`
var2="2 3 10 13" 
echo "vorher :" $var1
for liste in $var2 
do 
             var1=`echo $var1 | sed -e "s/\b$liste\b//g"`
done
echo "nachher:" $var1
ergibt folgende Ausgabe:

Code: Alles auswählen

vorher: 1 2 3 4 5 6 7 8 9 10
nachher: 1 4 5 6 7 8 9

Antworten