ubuntuusers.de

Aendern des Inhaltes einer Datei

Status: Gelöst | Ubuntu-Version: Nicht spezifiziert
Antworten |

dakkar

Avatar von dakkar

Anmeldungsdatum:
1. Juni 2006

Beiträge: 282

Hola 😉

folgendes problem:

ich habe eine Datei mit folgendem inhalt:

nuschelgerede
irgendwelche BUCHSTABEN

 12                          blafsel               blubber
 34                          schwall              gerede
  .
  . 
  .
 125                       fasel                  etcpp

so jetzt ist das ziel ALLE zeilen, in denen das erste NICHTLEERZEICHEN eine zahl ist um 1000 zu erhoehen.
Sprich das ziel sollte so aussehen.

nuschelgerede
irgendwelche BUCHSTABEN

 1012                          blafsel               blubber
 1034                          schwall              gerede
  .
  . 
  .
 1125                         fasel                  etcpp

hab ne weile mit dem sed rumgebastelt, bin aber zu dem ergebnis gekommen, dass der nicht besonders gut addieren kann 😀

wer ne idee wie ich das am besten anpacke?
Umsetzung muss zwingen bash sein. also keine perl etc konstrukte 😉

mfg
dakky

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4687

Wohnort: Berlin

sed ist erlaubt perl aber nicht!? sed ist auch keine reine Bash-Lösung. Na egal, hier ist ein wenig Python zum Vergleichen mit einer "erlaubten" Lösung. 😉

def main():
    lines = open('test.txt', 'r')
    for line in lines:
        try:
            number = int(line.split(None, 1)[0])
            line = line.replace(str(number), str(number + 1000), 1)
        except (ValueError, IndexError):
            pass
        print line,
    lines.close()

dakkar

(Themenstarter)
Avatar von dakkar

Anmeldungsdatum:
1. Juni 2006

Beiträge: 282

*schmunzelt* wortglauberei 😀

sed kann man problemlos in nem shell script nutzen ... perl nicht 😉

aber ich hab noch weiter gebastelt und hier mal meine aktuelle loesung:

sed -e "s/^ \([0-9][0-9]*\)/1\1/" -e "s/^  \([0-9][0-9]*\)/10\1/" -e "s/^   \([0-9][0-9]*\)/100\1/"  DATEI

tut was soll auch wenns echt nicht super wartbar ist.

mfg
dakky

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4687

Wohnort: Berlin

Wieso kann man Perl nicht in einem Shell-Skript benutzen!? Man kann sogar das ganze Shellskript in Perl implementieren.

Hello.World

Anmeldungsdatum:
18. Januar 2006

Beiträge: 156

dakkar hat geschrieben:

sed kann man problemlos in nem shell script nutzen ... perl nicht 😉

Doch, z. B. so:
perl -e 'print "hello, world\n"'

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17621

Wohnort: Berlin

Bash kann gut Ganzzahlarithmetik:

foo=34
echo $((1000+foo))

@dakkar:

  7 sieben
 12   Zwilf
 340 dreivierzich
9342 schwall


Das klappt mit Deinem Code gar nicht.
Mal wird 100 addiert, mal nix - nur mit viel Glück 1000.

Ich würde mit sed nur die Zahl aus der Zeile rausschneiden.

dakkar

(Themenstarter)
Avatar von dakkar

Anmeldungsdatum:
1. Juni 2006

Beiträge: 282

@hello world
ok da hast du recht.
nur ist halt
1. mein perl eher schlecht als irgendwas,
des weiteren ist halt perl bei uns inner firma keine standardsprache
und ausserdem finde ich es persoenlich wirklich eklig in einem script auf einmal ne ganz andere sprache zu nutzen.

@user unknown

doch der geht schon ganz gut. die anzahl der leerzeichen vor der ersten zahl sind relevant. bei einem leerzeichen wird nur ne 1 davorgeschrieben, bei zwei leerzeichen 10 und bei 3 leerzeichen ne 100. somit sind alle in diesem fall moeglichen faelle abgedeckt

is mir klar dass es vielleicht eher ne gefrickelte loesung ist, aber naja *g*

dakky

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4687

Wohnort: Berlin

Diese Besonderheit mit den Leerzeichen ist aus Deinen Beispieldaten aber nicht ersichtlich gewesen. Hier noch eine Lösungsidee:

while read LINE
do
    NUMBER=$(echo $LINE | \
             grep --only-matching --extended-regexp '^[ \t]*([0-9]+)')
    if [ $NUMBER ]
    then
        LINE=$(echo $LINE | sed "s/$NUMBER/$(($NUMBER + 1000))/")
    fi
    echo $LINE
done

Daten werden von der Standardeingabe erwartet.

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17621

Wohnort: Berlin

Marc 'BlackJack' Rintsch hat geschrieben:

Diese Besonderheit mit den Leerzeichen ist aus Deinen Beispieldaten aber nicht ersichtlich gewesen.

Genau.
Auch daß es keine Zahlen gibt, die bereits 1000 oder größer sind.
Von negativen Zahlen ganz zu schweigen.

Genaugenommen ist aber die Fragestellung mit dem Beispiel schon als defekt zu erkennen:

so jetzt ist das ziel ALLE zeilen, in denen das erste NICHTLEERZEICHEN eine zahl ist um 1000 zu erhoehen.
Sprich das ziel sollte so aussehen.


denn das erste Nichtleerzeichen ist eine Ziffer, keine Zahl.

Aber gut - wollen wir mal nicht so sein. 😉

dakkar

(Themenstarter)
Avatar von dakkar

Anmeldungsdatum:
1. Juni 2006

Beiträge: 282

sry 😉 hat sich aber auch erst nach meinem post herausgestellt, dass die anzahl der leerzeichen insofern relevant ist, da sie die groesse der folgenden zahl angeben und somit es moeglich ist die fuehrenden stellen zu erkennen.

trotzdem danke nochmal 😉

dakky

Sid_Burn

Anmeldungsdatum:
23. Oktober 2004

Beiträge: 2159

dakkar hat geschrieben:

und ausserdem finde ich es persoenlich wirklich eklig in einem script auf einmal ne ganz andere sprache zu nutzen.

Bash ist doch fast keine eigene Sprache, sondern besteht doch nur daraus andere Programme aufzurufen die alle ihre komplett eigene Syntax haben.

sed kann man problemlos in nem shell script nutzen ... perl nicht

Perl besitzt extra für die Verwendung in Shell Skripts Parameter die du angeben kannst, womit es eine sehr gute Alternative zu sed, awk wird.

Dein Beispiel würde als Perl Oneliner folgendermaßen aussehen:

perl -pe 's/^(\d+)/ sprintf "%04d", $1 + 1000 /e' datei.txt

Hiermit würde du datei.txt verändern. Möchtest du die Änderungen direkt in der Datei schreiben lassen musst du nur den Parameter "-i" hinzufügen. Möchtest du eine Backup Kopie vorher von der Datei erstellen, dann einfach hinter -i noch ein kürzel angeben z.B "-i.bak".

Wenn du -i weg lässt schreibt er defaultmäßig zu STDOUT. Womit du die Ausgabe mit weiteren Pipes bearbeiten könntest. Gibt du keine Datei an. Hier in dem beispiel datei.txt dann liest er automatisch von STDIN. Somit es das Konstrukt optimal in einer Shell einsetzbar. Folgendes Beispiel von "useless use of cat" soll es verdeutlichen.

cat datei.txt | perl -pe 's/^(\d+)/ sprintf "%04d", $1 + 1000 /e' | grep '1012'

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17621

Wohnort: Berlin

bash-bashing geht hier: http://forum.ubuntuusers.de/topic/125204/ weiter

Antworten |