• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

Zeilen vertauschen mit sed

Hallo,

ich brauche ein bash script, dass in einer Textdatei zwei Zeilen vertauscht. Die eingelesenen Dateien enthalten unterschiedlich viele Zeilen, d.h die gesuchten Zeilen haben leider keine feste Zeilennummer. Die Datei sieht etwa so aus:

xxxxx
xxxxx
WGHT 123
xxxxx
xxxxx
xxxxx
END

WGHT 234
xxxxx

Nun soll die erste Zeile WGHT mit der zweiten Zeile WGHT ersetzt werden. Das zweite WGHT kann dabei entfernt werden.

Hat dafür jemand eine Idee?

VIELEN DANK!

thomson2525
 
Thomson2525 schrieb:
Nun soll die erste Zeile WGHT mit der zweiten Zeile WGHT ersetzt werden. Das zweite WGHT kann dabei entfernt werden.
Kommen immer zwei WGHT-Zeilen vor? Oder kann es auch passieren, dass es nur eine von beiden ohne mehr als zwei gibt?
 
Hallo,

es kommen immer nur zwei WGHT vor. Die Datei wird durch ein Programm erzeugt, das das erste WGHT für seine Berechnung benutzt und dann in einem OUTPUT einen Vorschlag für einen neuen Wert für WGHT macht. Dieser Output enthält auch das Input-File. Diesen neuen Wert möchte ich automatisch oben in die Anweisungen einfügen lassen und das Programm durch das Script neu starten. Das wiederhole ich, bis sich der Wert nicht weiter ändert.

Zur besseren Übersichte könnte man den alten Wert auch behalten und zum Kommentar (rem) machen. Der neue Wert könnte gleich in die nächste Zeile.

Ich hoffe das hilt weiter.

Thomson2525
 
Mal ein Anfang:
Hier ein Perl-Skript, das eine Datei "x" verarbeitet:
Code:
#!/usr/bin/perl

use warnings;
use strict;

open(FH, "<x");

my @a = <FH>;

close(FH);

my $i;
my @b;

for($i = 0; $i <= $#a; $i++)
{
    if($a[$i] =~ m/WGHT /)
    {
        push(@b, $i);
        push(@b, $a[$i]);
    }
}

$a[$b[0]] = $b[3];
$a[$b[2]] = $b[1];

print @a;

# Bzw.:
# open(FH, ">x.out");
# print FH @a;
# close(FH);

Als Einzeiler sieht das dann so (häßlich :)) aus:
Code:
cat x | perl -e '@a=<>;for($i= 0;$i<=$#a;$i++){if($a[$i]=~m/WGHT /){push(@b,$i);push(@b, $a[$i]);}}$a[$b[0]] = $b[3];$a[$b[2]] = $b[1];print @a;'
Am regulären Ausdruck könnte man noch etwas feilen ...

Viele Grüße
 
Hallo,

VIELEN DANK!! ;-) Das Script tut genau das, was es soll. Bin erstaunt, welch lange reg. Expression da gebraucht wird.


bis zum nächsten Mal


THomson2525
 
Wollte gerade nach deiner Antowort sehen, un schon sehe ich eine komplette Lösung? Respekt!
Thomson2525 schrieb:
VIELEN DANK!! ;-) Das Script tut genau das, was es soll. Bin erstaunt, welch lange reg. Expression da gebraucht wird.
Die Regular Expression ist eigenlich nur das da:
Code:
/WGHT /
Ich weiß aber auch nicht, was man daran noch feilen könnte...

Man könnte die for-schleife vereinfachen und muss nicht unbedingt mit arrays+push arbeiten, aber das ist eigenlich auch egal :)

Wie heißt es so schön: TIMTOWTDI
 
Ich weiß aber auch nicht, was man daran noch feilen könnte...
Ich dachte z.B. daran, zu prüfen, ob "WGHT" am Zeilenanfang oder in der Mitte vorkommt usw.

Aber ist doch schön, daß es zu Deiner Zufriedenheit läuft :D.

@notoxp: Bestimmt kriegst Du auch bald wieder ein Perl-Skript zum schreiben ab; je mehr hilfsbereite Leute, um so besser :D.

Viele Grüße
 
Hallo,

hab ihm noch ein /^WGHT/ gegönnt. Der String ist (wenn er aktiv ist) immer an erster stelle. Können sonst noch "rem WGHT" vorhanden sein. die sollen unangetastet bleiben. Jetzt sind noch ein wenig optisches tuning notwendig, aber der core steht!

Thomson2525
 
Oben