Zeile in Datei ändern?

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
Yadgar
Beiträge: 983
Registriert: 22.11.2010 22:11:08
Wohnort: Qal'a-ye Nil, Bergisch-Afghanistan (linksrheinische Exklave)
Kontaktdaten:

Zeile in Datei ändern?

Beitrag von Yadgar » 08.03.2020 20:34:59

Hi(gh)!

In einer riesenlangen (zig Millionen Zeilen) POV-Ray-Datei (ASCII-Text) muss in Zeile Nr. 12967207 ein Komma entfernt werden. Mit KWrite hinscrollen würde viel zu lange dauern - wie stelle ich das am besten an?
Bis bald im Khyberspace!

Yadgar

If operating systems were countries, Linux would be pre-1978 Afghanistan: an all-time favourite among alternative globetrotters, but shunned by mainstream tourists because of its lack of fancy beaches, shortage of alcoholic beverages and its fondness of beards...

JTH
Moderator
Beiträge: 3077
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: Zeile in Datei ändern?

Beitrag von JTH » 08.03.2020 20:48:04

Etwa so:

Code: Alles auswählen

$ sed -i "12967207s/,//" POV-Ray.Datei
Zu beachten: Mit -i wird direkt in der angegebenen Datei ersetzt.
Manchmal bekannt als Just (another) Terminal Hacker.

Benutzeravatar
Yadgar
Beiträge: 983
Registriert: 22.11.2010 22:11:08
Wohnort: Qal'a-ye Nil, Bergisch-Afghanistan (linksrheinische Exklave)
Kontaktdaten:

Re: Zeile in Datei ändern?

Beitrag von Yadgar » 08.03.2020 21:34:26

Hi(gh)!
JTH hat geschrieben: ↑ zum Beitrag ↑
08.03.2020 20:48:04
Etwa so:

Code: Alles auswählen

$ sed -i "12967207s/,//" POV-Ray.Datei
Zu beachten: Mit -i wird direkt in der angegebenen Datei ersetzt.
Danke für den Tipp! Rechne schon mal damit, dass demnächst in POVghanistan ein bislang namenloser Viertausender im Mittleren Hindukusch nach dir benannt wird - Koh-e JTH, das ist doch was, oder?

Now playing: Parallels, live 1978 (Yes)
Bis bald im Khyberspace!

Yadgar

If operating systems were countries, Linux would be pre-1978 Afghanistan: an all-time favourite among alternative globetrotters, but shunned by mainstream tourists because of its lack of fancy beaches, shortage of alcoholic beverages and its fondness of beards...

uname
Beiträge: 12396
Registriert: 03.06.2008 09:33:02

Re: Zeile in Datei ändern?

Beitrag von uname » 09.03.2020 15:00:54

Du hättest natürlich auch den Editor Vim bemühen können.

Code: Alles auswählen

12967207G
12967207gg
:12967207<CR>
Und dann an der Stelle das Komma z. B. mit "x" löschen.


Getestet nur mit einer 5 Millionen Zeilen langen Datei. War zu faul eine größere Datei zu erzeugen.

tobo
Beiträge: 2336
Registriert: 10.12.2008 10:51:41

Re: Zeile in Datei ändern?

Beitrag von tobo » 09.03.2020 19:20:11

Ist vi/vim vorhanden, dann hätte es Vorteile den ex-Mode benutzen:

Code: Alles auswählen

ex - POV-Ray.Datei <<EOF
12967207s/,//
wq
EOF
Alternativ natürlich auch mit ed.

JTH
Moderator
Beiträge: 3077
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: Zeile in Datei ändern?

Beitrag von JTH » 09.03.2020 19:24:35

tobo hat geschrieben: ↑ zum Beitrag ↑
09.03.2020 19:20:11
Alternativ natürlich auch mit ed.
Ich dachte eigentlich, Meillo wirft das noch in die Runde ;)
Manchmal bekannt als Just (another) Terminal Hacker.

Benutzeravatar
Meillo
Moderator
Beiträge: 9225
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Zeile in Datei ändern?

Beitrag von Meillo » 09.03.2020 19:53:04

Das Problem war mit der ersten Antwort ja schon geloest.

Den Ansatz mit ex finde ich am besten. (vi (also der grafische Teil des Doppeleditors) ist hier nur unnoetiger Ballast.)

So sehr ich ed auch mag, in solchen Faellen verwende ich ihn nicht. Wie alle alten Unix-Tools hat er seine Massengrenzen (Zeilenlaenge und Co.). Ein Vim kommt mit allem zurecht, ein ed nicht unbedingt, bzw. ist er nicht dafuer ausgelegt. Vieles klappt, aber nicht jeder Fall zwangslaeufig. Deshalb wuerde ich in dem Fall einen Vim im ex-Mode nutzen.


Der ex ist im Uebrigen ein interessanter aber in eigenstaendiger Weise kaum genutzer Editor. Er ist recht faehig, dadurch aber leider auch nicht so schoen klein und einfach wie der ed.
Use ed once in a while!

Benutzeravatar
heisenberg
Beiträge: 4123
Registriert: 04.06.2015 01:17:27
Lizenz eigener Beiträge: MIT Lizenz

Re: Zeile in Datei ändern?

Beitrag von heisenberg » 09.03.2020 21:08:02

vi(m) braucht beim editieren so einer riesen Datei aber auch jede Menge RAM.

sed z. B. nicht weil er die Datei nur zeilenweise liest. (ex auch nicht?)

Hier mal ein Beispiel mit meinem USB-Stick-Backup(2 GB)

Code: Alles auswählen

 
du -sm muellhalde/usbstick.raw 
2105  muellhalde/usbstick.raw

/usr/bin/time sed -n '12432453p'  muellhalde/usbstick.raw 
0.71user 0.30system 0:01.02elapsed 100%CPU (0avgtext+0avgdata 3812maxresident)k
0inputs+0outputs (0major+547minor)pagefaults 0swaps

/usr/bin/time vim -c ":q" muellhalde/usbstick.raw
22.73user 1.39system 0:24.13elapsed 100%CPU (0avgtext+0avgdata 3762888maxresident)k
0inputs+64outputs (0major+940343minor)pagefaults 0swaps

Benutzeravatar
Meillo
Moderator
Beiträge: 9225
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Zeile in Datei ändern?

Beitrag von Meillo » 09.03.2020 21:17:58

heisenberg hat geschrieben: ↑ zum Beitrag ↑
09.03.2020 21:08:02
vi(m) braucht beim editieren so einer riesen Date aber auch jede Menge RAM.

sed z. B. nicht weil er die Datei nur zeilenweise liest. (ex auch nicht?)
Das ist ein guter Aspekt. vi/ex legen normalerweise eine Kopie der zu editierenden Datei an, in der die Veraenderungen passieren, bis sie zurueckgeschrieben werden koennen. Darum kann man die Arbeitsergebnisse nach einem Programmabsturz auch recovern. (Was Vim konkret macht, weiss ich nicht.)

Allerdings verwenden wir hier ja `sed -i' (!) folglich reicht Lesen alleine nicht aus. Aber hier ebenfalls: Wie die Implementierung das konkret macht, entzieht sich meiner Kenntnis.

Code: Alles auswählen

 
du -sm muellhalde/usbstick.raw 
2105  muellhalde/usbstick.raw

/usr/bin/time sed -n '12432453p'  muellhalde/usbstick.raw 
0.71user 0.30system 0:01.02elapsed 100%CPU (0avgtext+0avgdata 3812maxresident)k
0inputs+0outputs (0major+547minor)pagefaults 0swaps

/usr/bin/time vim -c ":q" muellhalde/usbstick.raw
22.73user 1.39system 0:24.13elapsed 100%CPU (0avgtext+0avgdata 3762888maxresident)k
0inputs+64outputs (0major+940343minor)pagefaults 0swaps
Du muesstest hier schon `sed -i' verwenden, um aussagekraeftige Werte zu bekommen.

Und statt `vim' den Befehl `ex', dann einfach den Doppelpunkt vor den Ex-Befehlen weglassen. Der Kommandotrenner ist ein Pipe-Symbol. Also z.B.:

Code: Alles auswählen

ex -c '12432453p|q'
Allerdings nutzt ex/vi den Alternate Buffer des Terminals (oder so aehnlich). Folglich verschwindet die Ausgabe evtl. wenn der Editor beendet wird. Aber zum Zeitmessen kannst du es so machen.


Edit: Was viel RAM verbrauchen koennte, koennten auch lange Zeilen sein. In deinem Image hat es evtl. wenig Newlines. Das ist dann eine andere Situation wie wenn du Textdateien hast.
Use ed once in a while!

Benutzeravatar
heisenberg
Beiträge: 4123
Registriert: 04.06.2015 01:17:27
Lizenz eigener Beiträge: MIT Lizenz

Re: Zeile in Datei ändern?

Beitrag von heisenberg » 09.03.2020 21:32:27

Allerdings verwenden wir hier ja `sed -i' (!) folglich reicht Lesen alleine nicht aus. Aber hier ebenfalls: Wie die Implementierung das konkret macht, entzieht sich meiner Kenntnis.
sed -i ist ein normaler sed-Lauf in eine temporäre Datei. Diese Datei übeschreibt am Ende dann per mv die Originaldatei. Beschreibung dazu ist in der info-page von gnu sed.

Im vorliegenden Fall heisst dass: Die Datei wird einmal komplett gelesen und einmal fast komplett geschrieben.

Antworten