MacUser.de Community!  

  weitere Suchoptionen
Zurück   MacUser.de Community! > Mac OS > Mac OS X - UNIX

Terminal: Löschen der ersten/letzten Zeilen

Antwort
 
Themen-Optionen
Alt 08-02-2010, 10:51   #1 (permalink)
MU Mitglied
 
Benutzerbild von DarkThoughts
 
Registriert seit: 08.2007
Beiträge: 192
Terminal: Löschen der ersten/letzten Zeilen

Hallo zusammen

Ich bin im Terminal nicht ganz unerfahren, aber habe für folgendes Szenario gerade das richtige UNIX-Tool nicht zur Hand (im Kopf):

Ich möchte bei einer Textdatei die ersten/letzten n Zeilen löschen.

Hat jemand gerade eine Idee?

Danke & viele Grüsse
Andy
DarkThoughts ist offline   Mit Zitat antworten
Alt 08-02-2010, 10:58   #2 (permalink)
Super Moderator
 
Benutzerbild von lundehundt
 
Registriert seit: 02.2003
Ort: muc.de
Beiträge: 13.658
Blog-Einträge: 3
welchen editor benutzt du denn

in vi werden ganze Zeilen mit dd geloescht

[count]dd loescht die Anzahl der Zeilen aus [count], beginnend bei der aktuellen Zeile
lundehundt ist offline   Mit Zitat antworten
Alt 08-02-2010, 11:02   #3 (permalink)
MU Mitglied
 
Benutzerbild von martinibook
 
Registriert seit: 08.2005
Beiträge: 7.013
vielleicht mit tail xy.txt > xy_neu.txt und danach noch irgendwie mit less?

Oder man schreibt ein kleines Tool:

Datei einlesen
Zeilen zählen
von (Zeile 1 bis Zeilenzahl -2) { // man zählt 0, 1, 2, …, n-2, n-1
speichere Zeile in andere Datei
}
martinibook ist offline   Mit Zitat antworten
Alt 08-02-2010, 11:04   #4 (permalink)
MU Mitglied
 
Benutzerbild von DarkThoughts
 
Registriert seit: 08.2007
Beiträge: 192

Themenautor/in
Hey

Als Editor verwende ich grundsätzlich vi, das stimmt.
dd war mir auch bereits bekannt.
Ich suche aber nach einem Einzeiler, welcher sich auch in ein sh-Script einbinden lässt.

Also quasi irgendwas im Stil:
Code:
tail datei.txt > datei.txt
Nur halt eben nicht die letzten 10 Zeilen, sondern alle davor. =)
DarkThoughts ist offline   Mit Zitat antworten
Alt 08-02-2010, 11:08   #5 (permalink)
MU Mitglied
 
Benutzerbild von martinibook
 
Registriert seit: 08.2005
Beiträge: 7.013
So ein kleines Tool ist schnell geschrieben. Mal schauen, was man da machen kann.
martinibook ist offline   Mit Zitat antworten
Alt 08-02-2010, 11:09   #6 (permalink)
MU Mitglied
 
Benutzerbild von oneOeight
 
Registriert seit: 11.2004
Ort: Ruhrgebiet
Beiträge: 26.873
wenn du anzahl der zeilen kennst, kannst dann halt head nehmen...
head -n X file
ansonsten musst du halt mit wc -l die zeilen bestimmen...
oneOeight ist offline   Mit Zitat antworten
Alt 08-02-2010, 11:11   #7 (permalink)
Neues MU Mitglied
 
Registriert seit: 01.2010
Beiträge: 16
So was würde ich mit dem SED machen. Das ist quasi ein VI auf Kommandozeilenebene.
diger ist offline   Mit Zitat antworten
Alt 08-02-2010, 11:11   #8 (permalink)
MU Mitglied
 
Benutzerbild von DarkThoughts
 
Registriert seit: 08.2007
Beiträge: 192

Themenautor/in
Okay...

Code:
line_number=`wc -l datei.txt`
head -n $line_number datei.txt > datei.txt
Müsste soweit hinhauen.
Danke für die Tips.
DarkThoughts ist offline   Mit Zitat antworten
Alt 08-02-2010, 11:16   #9 (permalink)
MU Mitglied
 
Benutzerbild von martinibook
 
Registriert seit: 08.2005
Beiträge: 7.013
Wenn die Textdateien nicht zu groß sind, kannst du auch das hier nehmen:

Code:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;


public class Abhack {

	public static void main(String[] args) {
		
		if (args.length != 2) {
			System.out.println("Usage: java Abhack quelle ziel");
			System.exit(0);
		}
		
		File in = new File(args[0]);
		File out = new File(args[1]);
		
		ArrayList<String> daten = new ArrayList<String>();
		
		
		// Daten einlesen
		try {
			BufferedReader br = new BufferedReader(new FileReader(in));
			String line;
			while ((line = br.readLine()) != null) {
				daten.add(line);
			}
			
			br.close();
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		// Daten schreiben
		try {
			BufferedWriter bw = new BufferedWriter(new FileWriter(out));
			
			int anzahlZeilen = daten.size();
			
			for (int i = 1; i < anzahlZeilen-1; i++) {
				bw.write(daten.get(i)+"\n");
			}
			
			bw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		

	}

}
Das in "Abhack.java" speichern und mit "javac Abhack.java" kompilieren, dann mit "Java Abhack quelle ziel" ausführen.
martinibook ist offline   Mit Zitat antworten
Alt 08-02-2010, 11:20   #10 (permalink)
MU Mitglied
 
Benutzerbild von DarkThoughts
 
Registriert seit: 08.2007
Beiträge: 192

Themenautor/in
@martinibook

Danke für das Tool.
Eine Lösung dieser Art hätte ich schon selbst hingekriegt, ich wollte nur wissen, ob sich das Problem auf "einfachere" (Komplexität des Codes) Weise lösen lässt.
Performance & Fehlerbehandlung spielt nur eine untergeordnete Rolle, ist nur für Heimanwendung und kommt sehr selten zum Einsatz.

Wenn mir nun noch jemand sagen kann, ob es eine Möglichkeit gibt, den Inhalt der Textdatei zufällig auszugeben (zufällig nach Zeilen), bin ich definitiv glücklich und muss das ganze nur noch schnell scripten. =)
DarkThoughts ist offline   Mit Zitat antworten
Alt 08-02-2010, 11:25   #11 (permalink)
MU Mitglied
 
Benutzerbild von martinibook
 
Registriert seit: 08.2005
Beiträge: 7.013
Das lässt sich auch noch machen. Dabei soll jede Zeile nur einmal ausgegeben werden?

Da knallst du einfach zwischen Eingabe und Ausgabe noch ein Collections.shuffle(arrayList);, das Programm sieht dann so aus:

Code:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;


public class TextMischen {

	public static void main(String[] args) {
		
		if (args.length != 2) {
			System.out.println("Usage: java TextMischen quelle ziel");
			System.exit(0);
		}
		
		File in = new File(args[0]);
		File out = new File(args[1]);
		
		ArrayList<String> daten = new ArrayList<String>();
		
		
		// Daten einlesen
		try {
			BufferedReader br = new BufferedReader(new FileReader(in));
			String line;
			while ((line = br.readLine()) != null) {
				daten.add(line);
			}
			
			br.close();
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		// Zeilen mischen
		Collections.shuffle(daten);
		
		// Daten schreiben
		try {
			BufferedWriter bw = new BufferedWriter(new FileWriter(out));
			
			int anzahlZeilen = daten.size();
			
			for (int i = 0; i < anzahlZeilen; i++) {
				bw.write(daten.get(i)+"\n");
			}
			
			bw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		

	}

}
Wenn die Zeilen direkt ausgegeben werden sollen, dann kannst du das so machen:

Code:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;


public class TextMischen {

	public static void main(String[] args) {
		
		if (args.length != 1) {
			System.out.println("Usage: java TextMischen quelle");
			System.exit(0);
		}
		
		File in = new File(args[0]);
		
		ArrayList<String> daten = new ArrayList<String>();
		
		
		// Daten einlesen
		try {
			BufferedReader br = new BufferedReader(new FileReader(in));
			String line;
			while ((line = br.readLine()) != null) {
				daten.add(line);
			}
			
			br.close();
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		// Zeilen mischen
		Collections.shuffle(daten);
		
		// Zeilen ausgeben
		int anzahlZeilen = daten.size();
		
		for (int i = 0; i < anzahlZeilen; i++) {
			System.out.println(daten.get(i));
		}
		

	}

}
martinibook ist offline   Mit Zitat antworten
Alt 08-02-2010, 11:59   #12 (permalink)
MU Mitglied
 
Benutzerbild von DeineMudda
 
Registriert seit: 05.2005
Ort: 76xxx
Beiträge: 505
Zitat:
Zitat von DarkThoughts Beitrag anzeigen
Wenn mir nun noch jemand sagen kann, ob es eine Möglichkeit gibt, den Inhalt der Textdatei zufällig auszugeben (zufällig nach Zeilen), bin ich definitiv glücklich und muss das ganze nur noch schnell scripten. =)
Schau mal hier oder alternativ hier.
DeineMudda ist offline   Mit Zitat antworten
Alt 09-02-2010, 06:38   #13 (permalink)
Moderator
 
Benutzerbild von maceis
 
Registriert seit: 09.2003
Ort: /var/root
Beiträge: 15.504
Zitat:
Zitat von DarkThoughts Beitrag anzeigen
...
Code:
line_number=`wc -l datei.txt`
head -n $line_number datei.txt > datei.txt
...
Damit wirst Du hinterher eine leere datei.txt haben.
Ich sehe auch wenig Sinn darin, mit head alle Zeilen der Datei (wc -l datei.txt) auszugeben. Da müsste doch wenigstens noch 1 abgezogen werden, oder nicht?


Abgesehen davon kann man mit sed auf sehr einfache Weise die letzte Zeile einer Datei abschneiden:

Code:
sed -e '$d' infile > outfile 
oder von Zeile n bis zum Dateiende abschneiden

Code:
sed -e 'n,$d' infile > outfile 
oder diese Zeilen ausgeben und die anderen löschen

Code:
sed -ne '2,$p' infile > outfile 
usw.

Die Lösung von martini finde ich da doch etwas zu aufwändig.

Geändert von maceis (09-02-2010 um 06:49 Uhr).
maceis ist offline   Mit Zitat antworten
Alt 21-02-2010, 21:30   #14 (permalink)
Neues MU Mitglied
 
Benutzerbild von wurstdog
 
Registriert seit: 02.2010
Beiträge: 12
sed -n '1!p' <datei>|sed -n '$!p'

Moin,
das gibt Dir nicht die erste und nicht die letzte Zeile auf stdout aus.
Und mit Umleitung in die datei.txt

sed -n '1!p' <datei>|sed -n '$!p' > datei.txt
wurstdog ist offline   Mit Zitat antworten
Alt 03-03-2010, 23:07   #15 (permalink)
Neues MU Mitglied
 
Registriert seit: 04.2009
Beiträge: 2
Also mit dem Befehl von DarkThoughts

line_number=`wc -l datei.txt`
head -n $line_number datei.txt > datei.txt

erhalte ich erhalte ich eine Datei in der nur:

==> datei.txt <==
==> datei.txt<==

steht.

Mit dem Tipp von Maceis, um die letzte Zeile zu löschen wird meine Datei leer wenn ich die selbe Quell und Zieldatei habe.


Gibt es mit sed keine Möglichkeit nur die letzte zeile zu entfernen?

Wenn ich den befehl von wurstdog nehme und das "1!" entferne erhelte ich das gewünschte Ergebnis auch nur wenn Quelldatei nicht gleich Zieldatei...
bongobong ist offline   Mit Zitat antworten
Antwort

Terminal: Löschen der ersten/letzten Zeilen


Lesezeichen

Themen-Optionen


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Bei der ersten/letzten Datei auf Knopfdruck? DNStuff Mac OS X 2 04-02-2010 15:45
mac frischling mit letzten(ersten) fragen slatergotmac Mac OS X 6 02-03-2009 09:14
[Terminal] Alles Fenster/Tabs der letzten Sitzung öffnen rullator Mac OS X - UNIX 3 25-08-2008 22:17
PowerBook 12": Versehentliches Löschen von Zeilen Blattlaus MacBook, PowerBook, iBook 8 02-04-2007 10:53
terminal - die letzten sitzungen anzeigen lassen mlbrassman Mac OS X 3 24-08-2006 00:14

Alle Zeitangaben in WEZ +1. Es ist jetzt 06:03 Uhr.


Hilfe? MacUser.de Übersicht


Impressum | Werbung bei MacUser.de
MacUser.de © 2001-2009. All rights reserved

MacUser.de Hosted by
  hosteurope