[Linux] sed newline & meerdere spaties verwijderen

Pagina: 1
Acties:
  • 278 views sinds 30-01-2008
  • Reageer

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hey,
Ik wil graag met iets als: cat filename | sed 's/\n//g'
een bestand met meerdere regels aanpassen tot een bestand met 1 lange regel.
Bijv:
[Oud bestand]
line1
line2
line3
[/Oud bestand]
Moet worden
[Nieuw bestand]
line1|line2|line3
[/Nieuw bestand]

Het kan ook zijn dat er een willekeurig aantal spaties vooraan een regel staan. Die wil ik eigenlijk ook weg hebben. In perl of php heb je trim, maar hoe doe je zoiets in bash, als het al kan tenminste :)
Het oude bestand kan dus ook zo zijn:
[Oud bestand]
___line1
_____line2
__line3
[/Oud bestand]
* _ = spatie
En moet hetzelfde worden als eerder bij nieuw bestand aangegeven. Thnx

[ Voor 4% gewijzigd door Verwijderd op 30-12-2003 20:37 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Als je beschikking hebt over Perl kan je dat wel gewoon gebruiken, en je kan je programma ook nog op de commandline doen. Er is een bepaalde optie (-p?) dat hij op de input werkt.

Uit mijn hoofd:
code:
1
perl -p -e 's/abc/def/;'

Acties:
  • 0 Henk 'm!

Verwijderd

Lees eens `man sed`, dan zie je al dat je sed recept tussen '{' en '}' moet staan. Dan heb je nu alleen nog het probleem dat ie dan je escape niet accepteert en dus alle karakters 'n' vervangt door niets :)

Acties:
  • 0 Henk 'm!

  • blaataaps
  • Registratie: Juli 2001
  • Niet online
Verwijderd schreef op 30 december 2003 @ 20:43:
Lees eens `man sed`, dan zie je al dat je sed recept tussen '{' en '}' moet staan. Dan heb je nu alleen nog het probleem dat ie dan je escape niet accepteert en dus alle karakters 'n' vervangt door niets :)
Hier werkt sed anders prima zonder {} hoor, ben je niet indewar met awk?

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Verwijderd schreef op 30 december 2003 @ 20:43:
Lees eens `man sed`, dan zie je al dat je sed recept tussen '{' en '}' moet staan. Dan heb je nu alleen nog het probleem dat ie dan je escape niet accepteert en dus alle karakters 'n' vervangt door niets :)
Ok? Maar ik heb tot nog toe die {} niet gebruikt, en toch werkt sed steeds. Ik heb alleen geen verstand van regex, sowieso is sed geen sterk punt van me :) En hoe ik een newline character moet vervangen weer ik al helemaal niet, vandaar mijn vraag. \n is hoogstwaarschijnlijk niet de juiste waarde, maar geeft wel duidelijk aan wat ik wil, toch?

Dat met perl ga ik zeker proberen, maar het liefst heb ik een bash oplossing.

Acties:
  • 0 Henk 'm!

Verwijderd

blaataaps schreef op 30 december 2003 @ 20:45:
[...]

Hier werkt sed anders prima zonder {} hoor, ben je niet indewar met awk?
Jeps, alleen die single quotes om de regexp van de TS die doen het zeker niet ;) Althans hier bij mij in ieder geval niet. Je mag inderdaad ook de { en } eromheen weglaten..

[ Voor 15% gewijzigd door Verwijderd op 30-12-2003 20:48 ]


Acties:
  • 0 Henk 'm!

  • blaataaps
  • Registratie: Juli 2001
  • Niet online
Perl is tegenwoordig op heel veel systemen aanwezig hoor, en strikt genomen is sed ook geen bash, maar een los programma :)

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
blaataaps schreef op 30 december 2003 @ 20:47:
Perl is tegenwoordig op heel veel systemen aanwezig hoor, en strikt genomen is sed ook geen bash, maar een los programma :)
Daar moet ik je idd gelijk in geven.
Ik ga aan de gang met perl :)

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Laat ik het even anders doen. Tot nu toe heb ik dit: Niet echt het eenvoudigst denk ik, maar voor mij werkt het. Het gaat er dus om dat ik alle domeinnamen van een server te pakken krijg. hostname -d geeft alleen het hoofddomein.
code:
1
cat /etc/httpd/conf/httpd.conf | grep "ServerName www." | sed 's/\#/\ /' | sed 's/ServerName www\./\ /' | sed 's/\./\\./' | sed 's/     //' | sed 's/ //' | sed 's/^ /|/' | sort -u

Nu komen hier verschillende domeinen uit, maar elk op een eigen regel. Wat verander ik aan mijn commando doolhof om alles achterelkaar te krijgen? En spaties moeten op een betere manier worden verwijderd aan het begin vd regel
Bedankt

Acties:
  • 0 Henk 'm!

  • oVRoM
  • Registratie: Juli 2000
  • Niet online
Ik zou het zo doen (ff snel in elkaar geprutst, geen commentaar svp :)):

Perl:
1
2
3
4
5
6
#!/usr/bin/perl
for (<STDIN>) {
chomp;
s/^\s*//;
print;
}


odysseus: True, is een automatisme om die g er achter te zetten denk ik ;)
Heb ook even het hele overbodige $data weggehaald, was ook nergens voor nodig :)

[ Voor 57% gewijzigd door oVRoM op 30-12-2003 21:09 . Reden: Iets logischer gemaakt en tipje van odysseus verwerkt :) ]


Acties:
  • 0 Henk 'm!

Verwijderd

Een willekeurige reeks spaties verwijder je door het te pijpen naar:
code:
1
sed 's/^\ *//g'

Weird overigens, want nu pakt ie wel de single quotes hier, terwijl dat net mte die \n geen enkel effect gaf op een testbestand. Nou ja. Ik heb niets gezegd ;))

Jeps eens :) overbodige g mag inderdaad weg ja, zoals gezegd een automatisme :)

[ Voor 16% gewijzigd door Verwijderd op 30-12-2003 21:10 ]


Acties:
  • 0 Henk 'm!

  • odysseus
  • Registratie: Augustus 2000
  • Laatst online: 10-09 19:53

odysseus

Debian GNU/Linux Sid

Kleine optimalisatie: verwijder de '/g' aan het eind van de regexp. Je wilt immers toch alleen aan het begin van de regel iets verwijderen en dat begin komt per $data maximaal één keer voor :).

edit:

Was eigenlijk een antwoord op oVRoM, maar geldt ook voor de reply boven mij :)

[ Voor 20% gewijzigd door odysseus op 30-12-2003 21:07 ]

Leven is het meervoud van lef | In order to make an apple pie from scratch, you must first create the universe.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Verwijderd schreef op 30 december 2003 @ 21:05:
Een willekeurige reeks spaties verwijder je door het te pijpen naar:
code:
1
sed 's/^\ *//g'

Weird overigens, want nu pakt ie wel de single quotes hier, terwijl dat net mte die \n geen enkel effect gaf op een testbestand. Nou ja. Ik heb niets gezegd ;))

Jeps eens :) overbodige g mag inderdaad weg ja, zoals gezegd een automatisme :)
Werkt perfect! Bedankt.
Nu nog wat voor die aparte regels > 1 regel. Toch nog een andere optie dan perl? Ik ben namelijk niet echt een perl wonder en begrijp het eerder genoemde script niet echt goed. Die var $data wat moet daar in staan, en hoe krijg ik dat er dan in?

Acties:
  • 0 Henk 'm!

  • oVRoM
  • Registratie: Juli 2000
  • Niet online
Verwijderd schreef op 30 december 2003 @ 21:14:
[...]

Werkt perfect! Bedankt.
Nu nog wat voor die aparte regels > 1 regel. Toch nog een andere optie dan perl? Ik ben namelijk niet echt een perl wonder en begrijp het eerder genoemde script niet echt goed. Die var $data wat moet daar in staan, en hoe krijg ik dat er dan in?
Die $data var heb ik al weggehaald... Die kreeg de standard input, lijn voor lijn zeg maar.

Perl:
1
#!/usr/bin/perl

Perl :)
code:
1
for (<STDIN>) {

Voor elke regel die je op je standard input binnen krijgt...
code:
1
chomp;

Verwijder de newline
code:
1
s/^\s*//;

Vervang 0 of meer spaties aan het begin van de regel met niets
code:
1
print;

en geef het weer :)
code:
1
}

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
JiHaaaaaaa, gelukt.

Erg bedankt voor jullie uitermate snelle hulp en suggesties. Ik heb er veel aan gehad.
Wat betreft het weghalen van die newline's, dat schijnt niet met sed te kunnen, maar we hebben een ander commando, 'tr' een TRanslation command. Dit kan heel simpel een \n commando vervangen door niks.
Mijn commando ziet er nu zo uit. En de output is precies wat ik hebben moet :)
code:
1
2
cat /etc/httpd/conf/httpd.conf | grep "ServerName www." | sed 's/\./\\./' |
sed 's/ServerName www\\./\.*/' | sed 's/^\ *//' | sed 's/$/|/' | sort -u | tr -d '\n'

sort -u : dubbele records verwijderen
tr -d '\n' : newline karakter verwijderen

Hier vond ik de oplossing, voor de geïnteresseerden: http://www.student.northpark.edu/pemente/sed/sedfaq5.html Bij kopje 5.10
Groeten, Hans
Pagina: 1