Aktuelle Zeit: 22. Aug 2014, 21:36

[gelöst] Leerzeichen und Tabs aus Textdatei entfernen...

Alles rund um die verschiedenen Konsolen und shells sowie die Programmierung unter Linux

Moderator: Moderatoren

[gelöst] Leerzeichen und Tabs aus Textdatei entfernen...

Beitragvon rethus » 11. Jul 2006, 13:49

Hallo,
ich möchte aus einer Textdatei alle Tabs entfernen, und zusätzlich alle Zeilenumbrüche, die von 2 Tabs gefolgt sind.

Dazu hab ich mich im Netz schon was kundig gemacht und folgenden Ansatz gefunden:

Code: Alles auswählen
tr -s [:blank:] ' ' < eingangstext.txt > ausgangstext.txt


http://www.linux-user.de/ausgabe/2005/02/073-zubefehl/index.html

Allerdings fehlt mir noch die genaue Kombination, das alles rund läuft.
Denn der obige Befehl zieht lediglich Leerzeichen >2 raus.

Wie gesagt benötige ich aber auch die funktion, das nur dir Zeilenumbrüche entfernt werden, die von Tabs gefolgt sind.

Hat jemand eine Idee?
Vielleicht kann mir da jemand helfen.
Zuletzt geändert von rethus am 15. Aug 2006, 18:02, insgesamt 1-mal geändert.
Benutzeravatar
rethus
Advanced Hacker
Advanced Hacker
 
Beiträge: 1028
Registriert: 17. Sep 2004, 10:21
Wohnort: Kerpen

Beitragvon oc2pus » 11. Jul 2006, 13:52

Reguläre Ausdrücke bestimmen mit diesem kleinen Tool:
http://txt2regex.sourceforge.net/

Txt2regex is a Regular Expression Wizard that converts human sentences to regexes. In a simple interactive console interface, the user answer questions and the program build the regexes for more than 20 programs, like Vim, Emacs, Perl, PHP, Python, Procmail and OpenOffice.org. It is a Shell Script 100% written with Bash builtin commands. No compilation or extra commands are needed, just download and run.


Supported programs (23)
AWK, ed, egrep, Emacs, expect, find, gawk, grep, lex, lisp, mawk, MySQL, OpenOffice.org, Perl, PHP, Postgres, Procmail, Python, SED, Tcl, VBscript, VI, Vim.
tell people what you want to do, and they'll probably help you to do it.
PackMan
LinWiki : Das Wiki für Linux User
Benutzeravatar
oc2pus
Ultimate Guru
Ultimate Guru
 
Beiträge: 6507
Registriert: 21. Jun 2004, 13:01

Beitragvon rethus » 11. Jul 2006, 14:08

Naja, mir würde schon aussreichen zu wissen, was ein leerzeichen und was ein Tab in Form von Regulären Ausddrücken wäre.

PS: Hab noch folgende möglichkeit gefunden, wobei mir da auch wieder die Suche nach dem genauen Muster fehlen: "Zeilenumbruch >> 2x Tab"

Code: Alles auswählen
sed -e '/^[ ]*$/d' AlteDatei > NeueDatei
(ist auch wieder nur für leerzeichen...
Benutzeravatar
rethus
Advanced Hacker
Advanced Hacker
 
Beiträge: 1028
Registriert: 17. Sep 2004, 10:21
Wohnort: Kerpen

Beitragvon oc2pus » 11. Jul 2006, 14:13

rethus hat geschrieben:Naja, mir würde schon aussreichen zu wissen, was ein leerzeichen und was ein Tab in Form von Regulären Ausddrücken wäre.


und warum lässt du es dir dann nicht von dem kleinen Tool verraten ?
das ist ein bash-script, ist also in null-komma-Nix installiert ...

btw: "\t" ist ein TAB
tell people what you want to do, and they'll probably help you to do it.
PackMan
LinWiki : Das Wiki für Linux User
Benutzeravatar
oc2pus
Ultimate Guru
Ultimate Guru
 
Beiträge: 6507
Registriert: 21. Jun 2004, 13:01

Beitragvon rethus » 11. Jul 2006, 14:36

Ok, hab mir das Progie gezogen... ist n tolles Programm... Sieht komlizierter aus als ist.... werde ich sicher noch oft zum Coden brauchen, aber mit meinem Problem bin ich immer noch nicht weiter...

Also ich habe Beispielsweise folgen Text:
(Ich füg mal >> f+r Zeilenumbruch und -| für Tab ein

Code: Alles auswählen
UKZLAG>>
Attribut FAHR_UKZLager >>
Definiert durch Basisattribut   :   UnternehmenKZLager >>
Definition Basisattribut   :   Unternehmenskennzeichen LAGer . >> Bezeichnet zusammen mit der Filial->>
-|    -|      nummer des Lagers (FILLAG) eindeutig das Lager. Standardbestandteil >>
-|  -|      des Primärschlüssels der meisten LVS-Tabellen. >>
Einschränkung Wertebereich   :   Wird in den LVS-Programmen durch eine Parameterdatei beim Start der >>
-|  -|      Server-Programme eingestellt.


Also vor dem Doppelpunkt ist eine Bezeichnung der Zeile, und dahinter der Text, der ohne Umbrüche und Tabs dargestellt werden soll.

Mein Ansatz war:
    1. tr -s '\n\t\t' '\n' < db_daten.txt >db_new.txt
    2. sed -e '/^[\n\t\t]*$/d' db_daten.txt >db_new.txt


1. zog alles an Zeilenumbrüchen raus, so das ich einen Textbrei erhalte...
2. bewirkt irgendwie überhaupt nichts
Benutzeravatar
rethus
Advanced Hacker
Advanced Hacker
 
Beiträge: 1028
Registriert: 17. Sep 2004, 10:21
Wohnort: Kerpen

Beitragvon oc2pus » 11. Jul 2006, 14:52

probiere mal:

Code: Alles auswählen
sed -e '/[\t].*\|[\n][\t]\{2\}.*/d' < EINAGBE.txt


durch "|" wird das ODER dargestellt
aslo entweder TAB gefolgt von Zeichen
ODER ZeilenUmbruch gefolgt von TAB TAB wertden durch "NIX" ersetzt.
tell people what you want to do, and they'll probably help you to do it.
PackMan
LinWiki : Das Wiki für Linux User
Benutzeravatar
oc2pus
Ultimate Guru
Ultimate Guru
 
Beiträge: 6507
Registriert: 21. Jun 2004, 13:01

Beitragvon rethus » 11. Jul 2006, 15:08

Danke, das ist schon ganz gut, aber leider funzt es noch nicht...
Das Problem ist, das die Zeilen jeweils gelöscht werden, anstatt die entsprechenden Zeichen einfach rauszuziehen.

Derzeit habe ich folgenden Befehl:
Code: Alles auswählen
sed -e '/[\t]\{2\}.*/g' db_daten.txt > db_new.txt
Benutzeravatar
rethus
Advanced Hacker
Advanced Hacker
 
Beiträge: 1028
Registriert: 17. Sep 2004, 10:21
Wohnort: Kerpen

Beitragvon oc2pus » 11. Jul 2006, 15:17

rethus hat geschrieben:Danke, das ist schon ganz gut, aber leider funzt es noch nicht...
Das Problem ist, das die Zeilen jeweils gelöscht werden, anstatt die entsprechenden Zeichen einfach rauszuziehen.

ok, dann muss am Ende /d durch /g erstezt werden so wie du es getan hast.

lass deinen ersten Befehl mit dem "tr ... " mal weg, dann sollte es besser funktionieren. Oder hast du den gar nicht mehr in Betrieb ?
tell people what you want to do, and they'll probably help you to do it.
PackMan
LinWiki : Das Wiki für Linux User
Benutzeravatar
oc2pus
Ultimate Guru
Ultimate Guru
 
Beiträge: 6507
Registriert: 21. Jun 2004, 13:01

Beitragvon rethus » 11. Jul 2006, 15:20

Den hab ich gar nicht mehr genutzt.

Bei obiger Befehlsingabe löscht er die Zeilen auch, allerdings bleibt die Zeile (leer) bestehen.
Bei /d nimmt de3r die Zeile ganz raus.
Benutzeravatar
rethus
Advanced Hacker
Advanced Hacker
 
Beiträge: 1028
Registriert: 17. Sep 2004, 10:21
Wohnort: Kerpen

Beitragvon oc2pus » 11. Jul 2006, 15:22

bei deinem Befehl werde 2 TAB gefolgt von belibigen Zeichen durch NIX ersetzt, deshalb.

lass mal den ".*" weg, dann werden nur die TABTAB Sequenzen zu NIX
tell people what you want to do, and they'll probably help you to do it.
PackMan
LinWiki : Das Wiki für Linux User
Benutzeravatar
oc2pus
Ultimate Guru
Ultimate Guru
 
Beiträge: 6507
Registriert: 21. Jun 2004, 13:01

Beitragvon rethus » 11. Jul 2006, 15:30

Geht auch nicht....
:-(
Benutzeravatar
rethus
Advanced Hacker
Advanced Hacker
 
Beiträge: 1028
Registriert: 17. Sep 2004, 10:21
Wohnort: Kerpen

Beitragvon oc2pus » 11. Jul 2006, 15:50

AARG es fehlte ja auch was wichtiges das "s" für substitute

entferne alle TABs
Code: Alles auswählen
sed -e 's/[\t]//g' <EINGABE.TXT


du kannst dann konkatenieren
Code: Alles auswählen
sed -e 'expr1' -e 'expr2' < EINGABE.TXT


habe grade keinen sed-fähigen Rechner hier ;)[/code]
tell people what you want to do, and they'll probably help you to do it.
PackMan
LinWiki : Das Wiki für Linux User
Benutzeravatar
oc2pus
Ultimate Guru
Ultimate Guru
 
Beiträge: 6507
Registriert: 21. Jun 2004, 13:01

Beitragvon rethus » 11. Jul 2006, 17:13

Also das ist es noch nicht so ganz.
Das Problem ist folgendes:

Wenn ich Ihm sage:
Code: Alles auswählen
sed -e 's/[\t]\{2\}//g' text1.txt > text2.txt

Macht er auch brav alles - also zieht alle doppelten tabs raus.

Aber sobald ich Ihm mit einem Zeilenumbruch kommen will:
Code: Alles auswählen
sed -e 's/[\n][\t]\{2\}//g' text1.txt > text2.txt

, macht er gar nichts mehr (die Datei sieht dann genauso aus wie die Quelldatei... keine Änderung)

Woran kann das nur liegen? Habs auch schon mit [\r] anstatt [\n] versucht... nix :-(
Benutzeravatar
rethus
Advanced Hacker
Advanced Hacker
 
Beiträge: 1028
Registriert: 17. Sep 2004, 10:21
Wohnort: Kerpen

Beitragvon sc_m » 11. Jul 2006, 17:37

Das Problem ist, dass sed grundsätzlich zeilenweise arbeitet, d.h. bei einem "\n" wird der aktuelle Puffer abgearbeitet und anschließend verworfen. Man kann aber mit einem zweiten Puffer ein wenig herumspielen:
Code: Alles auswählen
echo -e "eine Zeile,\n\t\tweiter,\n\t\tnoch weiter\nletzte Zeile\n" |
sed -ne '/^\t\t/{H;x;s/\n\t\t/ /;x;D}; x; 2,$p'
Ist es das, was du wolltest?

Edit: Etwas Kosmetik.
sc_m
Member
Member
 
Beiträge: 205
Registriert: 31. Okt 2005, 22:59
Wohnort: Frankfurt

Beitragvon abgdf » 11. Jul 2006, 20:36

Hallo,

ich hab hier eine Lösung in Python gebastelt.

Eingabedatei heißt "in", Ausgabedatei heißt "out", jeweils im Verzeichnis des Skripts. Bitte ggf. entsprechend ändern:

Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf8 -*-

f=file("in","r")
a=f.readlines()
f.close()

c=[]

for i in range(len(a)):

    c.append(a[i].replace("\t",""))

    if a[i][0:2]=="\t\t" and i != 0:
        c.pop()
        c.pop()
        c.append((a[i-1].rstrip("\n")+a[i]).replace("\t",""))

f=file("out","w")
f.writelines(c)
f.close()


Wie findest Du das so ?

Viele Grüße
abgdf
Guru
Guru
 
Beiträge: 2548
Registriert: 13. Apr 2004, 21:15

Beitragvon jengelh » 11. Jul 2006, 23:13

Wie wär's mit ... ?
Code: Alles auswählen
perl -e '$_=join"",<>;s/\n\t\t//gs;s/\t//gs;print' <test
jengelh
Guru
Guru
 
Beiträge: 4040
Registriert: 20. Nov 2004, 18:42

Beitragvon abgdf » 12. Jul 2006, 11:07

@jengelh:
Ist ja echt krass, was Du alles in einer Zeile unterbringen kannst :shock: :) !
Ich brauch da schon etwas länger:

Code: Alles auswählen
#!/usr/bin/env perl
use warnings;
use strict;

open (F, "in") or die;
my @a=<F>;
close(F);

my @c=();
my $ci=0;
my $i=0;

for ($i=0;$i<=$#a;$i++)
{
$c[$ci]=$a[$i];
$c[$ci] =~ s/[\t]//g;
$ci++;

if (substr($a[$i],0,2) eq "\t\t" && $i != 0)
{
pop(@c);
pop(@c);
$ci -= 2;

$c[$ci]=$a[$i-1];
chomp($c[$ci]);
$c[$ci]=$c[$ci].$a[$i];
$c[$ci] =~ s/[\t]//g;
$ci++;
}
}

open (F, ">out") or die;
print (F @c);
close(F);


Viele Grüße
abgdf
Guru
Guru
 
Beiträge: 2548
Registriert: 13. Apr 2004, 21:15

Beitragvon jengelh » 12. Jul 2006, 12:21

abgdf hat geschrieben:@jengelh:
Ist ja echt krass, was Du alles in einer Zeile unterbringen kannst :shock: :) !

Weniger ist besser, hat weniger potentielle Fehlerquellen.
Ich brauch da schon etwas länger:

Code: Alles auswählen
#!/usr/bin/env perl
use warnings;
use strict;

open (F, "in") or die;
my @a=<F>;
close(F);

my @c=();
my $ci=0;
my $i=0;

for ($i=0;$i<=$#a;$i++)
{
$c[$ci]=$a[$i];
$c[$ci] =~ s/[\t]//g;
$ci++;

if (substr($a[$i],0,2) eq "\t\t" && $i != 0)
{
pop(@c);
pop(@c);
$ci -= 2;

$c[$ci]=$a[$i-1];
chomp($c[$ci]);
$c[$ci]=$c[$ci].$a[$i];
$c[$ci] =~ s/[\t]//g;
$ci++;
}
}

open (F, ">out") or die;
print (F @c);
close(F);


Viele Grüße

Na mit deinem @c Array machst du keinen glücklich, denn nach jedem \n fängt ein neues Element an. Genau das aber stört, wenn du gerade \n im Suchen-und-Ersetzen-Muster hast.
jengelh
Guru
Guru
 
Beiträge: 4040
Registriert: 20. Nov 2004, 18:42

Beitragvon rethus » 12. Jul 2006, 12:31

Wow, danke schon mal für Eure Mühe.
Werde mich mal mit den verschiedenen Lösungen auseinandersetzen und euch dann eine Rückmeldung geben.

Danke schon mal!
Benutzeravatar
rethus
Advanced Hacker
Advanced Hacker
 
Beiträge: 1028
Registriert: 17. Sep 2004, 10:21
Wohnort: Kerpen

Beitragvon abgdf » 12. Jul 2006, 12:52

Weniger ist besser, hat weniger potentielle Fehlerquellen.


Das ist ein Argument. Andererseits ist eine längere Fassung vielleicht leichter nachzuvollziehen.

Na mit deinem @c Array machst du keinen glücklich


Solange das Problem gelöst wird, sollten alle glücklich sein.

Gruß
abgdf
Guru
Guru
 
Beiträge: 2548
Registriert: 13. Apr 2004, 21:15

Nächste

Zurück zu Konsole und Programmierung

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 0 Gäste