Hallo Ralf, hallo Sebastian, * Sebastian Helms schrieb am 20.Apr.2000:
* Ralf Steck wrote on 20 Apr 2000:
cat avp.set | grep .avp > set_inhalt.txt
Wieso so kompliziert? grep .avp avp.set > set_inhalt.txt macht das gleiche, wenn auch nicht unbedingt genau das gewollte. ;)
ls | grep .avp >> set_inhalt.txt
Dito. ls *.avp >> set_inhalt.txt macht zwar nicht exakt das gleiche, aber mehr das, was Du willst, es werden nur Dateinamen in set_inhalt.txt angefügt, die mit .avp enden und nicht solche, die irgendwo ein .avp stehen haben. Beim grep steht der Punkt aber nicht nur für sich selber, sondern für jedes Zeichen außer den Zeilenumbruch. Obiges Verhalten würdest Du exakt mit ls *?avp* >> set_inhalt.txt bekommen, aber das willst Du gar nicht. Ob Du überhaupt an set_inhalt.txt anhängen willst, gehe ich hier nicht ein, dazu unten mehr.
sort set_inhalt.txt
Wenn Du das eingibst, so erhälst Du auf der Standardausgabe, also Deinen Bildschirm eine zeilenweise sortierte Datei set_inhalt.txt. Die Datei selber bleibt aber so wie sie ist. Sie wird nicht sortiert. Was Du möchtest ist sort set_inhalt.txt> datei komm aber nicht auf die Idee für datei set_inhalt.txt zu nehmen, denn dann wirst Du überrascht sein. Sie ist anschließend leer.
uniq set_inhalt.txt
Hier gilt das gleiche wie oben. Die Datei set_inhalt.txt ändert sich nicht. Du kannst es übrigens einfacher machen indem Du oben sort -u sagst, dann wird uniq schon gleich ausgeführt.
rm < setinhalt.txt
Hast Du das mal ausprobiert? Nein, Du würdest eine Fehlermeldung bekommen. rm braucht ein Argument, nämlich was es löschen soll. rm ließt nicht von der Standardeingabe.
Ach Manno, immer wenn ich denke, dass ich einen Geniestreich abgeliefert aheb, kommt einer von euch Cracks und schüttelt das ganze in einer Zeile aus dem Handgelenk :-)
Nicht ärgern, lernen, lohnt sich. ;))
*g* Na, ich hatte mich aber auch gefreut... bis zu Bernds Kommentar... :-)
Sorry. ;))
( ls; recode ibmpc..lat1 avp.set ) | grep \.avp | sort | uniq | for file in `cat`; do rm $file; done
Nein. recode gibt normal nichts aus, sondern verändert die Datei. Wenn es in einer pipeline eingebaut ist, so gibt es aber auch aus. Entweder vorab ein recode ibmpc..lat1 avp.set und dann weiter oder aber ( ls; cat avp.set | recode ibmpc..lat1 ) | ... unbeschadet, ob Du das so überhaupt so willst. Dazu unten mehr. Kann sein, daß es auch noch einfacher geht. Dazu gibt es man recode oder imho auch info recode. (Nein ich mag info nicht.) man recode habe ich nur mal überflogen. Aber so wie Du es schreibst geht es nicht. Ich glaube auch nicht, daß recode überhaupt nötig ist. Es sei denn, es kommen Namen mit Umlaute oder ß vor. Das \r\n anstelle von \n macht aber grep und auch rm nichts aus. Anstelle der for-Schleife ist ein einfaches xargs besser. (...) | grep \.avp | sort -u | xargs rm -f xargs hängt einfach alles was es auf der Standardeingabe vorfindet als Argument hinten an. Die Argumente die xargs folgen werden zuerst genommen. Das erste Argument ist der Befehl. Hier also das rm. Das -f wird auch gleich dem rm angehangen. Es ist eine Option für das rm aber nicht für xargs. Option für xargs müssen wie bei andern Befehlen auch vor dem ersten Argument kommen. Nach dem rm -f hängt xargs seine gesammte Standardeingabe an. Also das was Ihr haben wollt. Es kann aber sein, daß dem rm die Argumente zu viel werden. Das kann man mit der Option -n für xargs regeln. Siehe hierzu man xargs. Aber ich glaube nicht, daß es zuviel wird. ls /dev|xargs echo hat es bei mir ohne murren getan und mehr Dateien als /dev wirst Du nicht haben. ;)) Das -f hinter dem rm ist dafür da, daß ohne murren gelöscht wird. Wenn man kein Schreibrecht auf einer Datei hat, so fragt rm erst nach, ob es wirklich gelöscht werden soll. Wenn man rm -f angibt, entfällt diese Frage und es wird einfach gelöscht. Notwendig zum löschen ist das Schreibrecht im Verzeichnis und nicht das Schreibrecht auf der Datei, die man löschen will.
Das \.avp ist, damit er nur ".avp" und nicht "xavp" findet.
Das ist so korrekt.
Ich gestehe, dass ich Klammer und ; noch nicht nachgeachaut habe.
; ist nur das Ende eines Befehls und kann immer durch ein Zeilenumbruch ersetzt werden und umgekehrt. (Nicht das ;; das zur Syntax von case gehört.) Aber habt Ihr Euch mal überlegt, was da überhaupt gemacht wird? Es werden alle Dateien mit einer bestimmten Endung gelöscht, die in einem Verzeichnis vorhanden sind und zusätzlich noch solche, mit ebendergleichen Endung die in einer Datei aufgeführt werden. Ist das Sinn der Sache? Das kann überhaupt nur Sinn machen, wenn sie in der Datei mit absoluten Pfad dastehen, denn sonst reicht es doch alle aus dem Verzeichnis zu löschen. Wenn ich Dirk recht verstanden habe, so will er alles löschen, was im Verzeichnis vorhanden ist, aber nicht in der Datei steht. Du löschst aber alles was im Verzeichnis vorhanden ist und zusätzlich, was in der Datei steht. Jeweils nur mit bestimmter Endung. Du mußt zugeben, das ist was ganz anders. Wie sieht Dein avp.set denn überhaupt aus? All das, was bisher geschrieben wurde funktioniert nur, wenn in avp.set einzelne Zeilen existieren in denen ein Dateiname steht und sonst nichts. Sonst darf die Zeichenfolge .avp nirgends in der Datei auftauchen, sonst gibt es Probleme. Ist dem so? grep gibt eine Zeile aus, auf der das Suchmuster paßt. Das heißt, wenn irgendwo in einer Zeile das Suchmuster auftaucht, so wird die gesammte Zeile ausgegeben und nicht nur das Wort. Es ist oftmals besser Kommentarzeilen vorher auszusortieren. Dazu gibt man vorher noch ein grep -v Suchmuster in der pipeline, wobei Suchmuster auf einen Kommentar paßt. Das wäre z.B. ...| grep -v "^#" | ... für normale Linux-Kommentare die mit # beginnen. Das ^ steht für Zeilenanfang. Es werden also nur Kommentare über ganze Zeilen gefunden. Das -v besagt nun, daß nur Zeilen auf denen das Suchmuster *nicht* paßt weitergeleitet werden. Kommentare werden somit aussortiert. Bei Deiner Datei avp.set kann das natürlich anders aussehen. Wenn in avp.set die Dateinamen nicht alleine in einer Zeile stehen, so muß noch was anders gemacht werden. Z.B noch ein sed eingefügt werden. Da spekuliere ich aber jetzt nicht drüber. Da bräuchte ich schon genauere Angaben. Lege Dir eine sortierte Datei an, die Du meinetwegen set-inhalt.txt nennst. Dateien brauchen bei Linux übrigens keinerlei Endungen zu haben. Endungen haben oftmals keine Bedeutung. set-inhalt tut es genauso gut. Aber egal. Das machst Du, indem Du grep \.avp$ avp.set | recode ibmpc..lat1 | sort -u > set-inhalt.txt sagst. Ob das grep so ausreicht, weiß ich wie gesagt nicht. Das $ steht für Zeilenende. Das recode habe ich doch mal gelassen, falls Umlaute vorhanden sind. Als nächstes suchst Du mit comm die Zeilen aus, die es in ls gibt aber nicht in set-inhalt.txt und löschst diese Dateien: ls | comm -23 - set-inhalt.txt | xargs rm -f comm vergleicht zwei sortierte Dateien. Hier - und set-inhalt.txt, dabei steht - für die Standardeingabe. comm gibt die Eingabe in drei Spalten wieder aus. In der ersten Spalte stehen Sachen, die es nur in der ersten Datei gibt, in der zweiten solche, die nur in der zweiten Datei stehen und in der dritten solche die gemeinsam sind. Steht in den deutschen Manpages übrigens falsch. In den englischen richtig. Funktioniert aber nur mit sortierten Dateien richtig. Aber set-inhalt.txt haben wir ja sortiert und ls gibt seine Zeilen ja auch sortiert aus. Wenn ls in eine Pipeline schreibt, so gibt es anders als auf dem Bildschirm die Dateien einzeln aus. Kann man sich mit ls|cat anschauen. Das -23 besagt, daß die zweite und dritte Spalte nicht ausgegeben werden soll. Es wird somit nur die erste Spalte ausgegeben, also nur Zeilen, die von ls kommen aber nicht in set-inhalt.txt stehen. Genau die, die gelöscht werden sollen. Zu xargs habe ich oben schon geschrieben. Da rm ein gefährlicher Befehl ist, würde ich dringend dazu raten erst mal einen Test zu machen wo anstelle des rm -f ein echo steht. Damit es nicht am Bildschirm vorbeirauscht auch noch ein less hinterher. Obige Zeile sieht dann wie folgt aus: ls | comm -23 - set-inhalt.txt | xargs echo | less Wenn da nur Dateien auftauchen, die auch wirklich gelöscht werden sollen, so kann man dann den echten Befehl ausführen.
Hab ch auch erst mit der Zeit gelernt.. :-)
Ja, ich auch. ;)) Sollten noch Fragen auftauchen, so fragt. Ansonsten gibt es da noch man cat man grep man recode man sort man uniq man comm man xargs und all die, die ich vergessen habe. ;)) Und wenn jetzt einer sagt, ich wüßte das alles schon, so sage ich nur nein, nicht ganz. recode kannte ich gar nicht (besser gesagt, ich hatte mich erinnert schon mal davon gehört zu haben) aber ein kleiner Test und ein Blick in den manpages reichte aus um festzustellen, daß da was nicht stimmte. Bernd -- ACK = ACKnowledge = Zustimmung | NAC = No ACknowledge = keine Zustimmung DAU = Dümmster Anzunehmender User | LOL = Laughing Out Loud = Lautes Lachen IIRC = If I Remember Correctly = Falls ich mich richtig erinnere OT = Off Topic = Am Thema (der Liste) vorbei |Zufallssignatur 11 --------------------------------------------------------------------- To unsubscribe, e-mail: suse-linux-unsubscribe@suse.com For additional commands, e-mail: suse-linux-help@suse.com