String in mehreren Dateien ersetzen

T

The Crusher

Grünschnabel
Hallo zusammen,

ich bräuchte ein Shell-Skript, das folgendes tut:

- lese alle Dateien im aktuellen Verzeichnis, die auf .html enden, ein
- ersetze in all diesen Dateien den String "/icon" durch "icon"
- speichere die Dateien dann wieder ab

Ist wahrscheinlich für euch Cracks hier kein Problem. :) Das blöde ist, dass ich das Skript eigentlich sofort brauche und so schnell werde ich es nicht hinbekommen. Bin noch unerfahren im Shell-Skripting und würde mich über Hilfe freuen !

Thanx,
The Crusher
 
Ich würde dir einen HTML-Editor empfehlen, welcher "Suchen und Ersetzen" kann, z.B. Bluefish. Das umständliche programmieren eines Shell-Skriptes wäre imho reine Zeitverschwendung! :)

EDIT: Oder hast du nur eine Konsole zur Verfügung? Dann ist Bluefish natürlich keine Lösung *g*


mfg hex
 
Nee, ich brauche definitv ein Shellskript ...
 
Code:
#!/bin/sh
WORKDIR=/dein/html/verzeichnis/

cd $WORKDIR
for i in `ls *.[hH][tT][mM][lL]`
do
   mv $i $i.tmp
   cat $i.tmp | sed -e 's/\/icon/icon/g' >> $i
   rm $i.tmp
done

So auf die schnelle.
 
Code:
find . -iname "*.html" -depth 1 -exec sed -i "" -e "s/\/icon/icon/g" {} \;

Gruss, Phorus
 
@Phorus:
Hehe, und wenn jetzt noch der Wolfgang seinen perl-Einzeiler vom Stapel lässt (*duck*), dann bestätigen wir wiedermal, dass doch nichts über kryptisch verkettete Befehle geht ;) .
 
Super ! Danke für die schnelle Hilfe, Jungs !
 
Cyber schrieb:
@Phorus:
Hehe, und wenn jetzt noch der Wolfgang seinen perl-Einzeiler vom Stapel lässt (*duck*), dann bestätigen wir wiedermal, dass doch nichts über kryptisch verkettete Befehle geht ;) .
:D :D
Hehe
auch wenn es verboten ist
perl -pi -e '~s|/\.icon|icon|' *html
IMHO mit GNU sed
sed -i -e '~s|/\.icon|icon|' *html

Gruß Wolfgang
 
Wolfgang_1 schrieb:
:D :D
Hehe
auch wenn es verboten ist
perl -pi -e '~s|/\.icon|icon|' *html
IMHO mit GNU sed
sed -i -e '~s|/\.icon|icon|' *html

Gruß Wolfgang

Arg, da hab ich vor lauter Bäumen den Wald nicht gesehen :)
 
Hallo ihr lieben,

der Einzeiler ist ja schon echt super.
Ich hab ein aehnliches Problem, aber ich glaube nicht das man es in eine Zeile packen kann.

Die Zeile...
Code:
 perl -pi -e '~s|subdomain\.domainname\.org|neu-subdomain\.domainname\.org|' *
...wandelt mir meinen String wie gewuenscht um.
subdomain.domainname.org wird umbenannt in neu-subdomainname.org

Leider wird aber auch...
neusubdomain.domainname.org umbenannt in
neu-neusubdomainname.org

Und da ist der haken. Ich muss alle ascii zeichen ausklammern vor dem subdomain.domain.org jedoch steht vor dem subdomain.domain.org of ein " , / , : oder leerzeichen die erlaubt sein soll. Wobei wir beim dem anscheinend sehr beliebten Thema Regular Expressions waeren .

Soweit hab ich mich schon schlau gemacht
[^0-9a-zA-Z] vor subdomain.domain.org sollen verboten sein.
fuer Grep also [[:alnum:]]
Die restlichen moeglichen Zeichen die evtl zu erwarten waeren und eine Aenderung ausschliessen sollen:
- _ @ # .
[[:alnum]_-\@\#\.]

Also muss ich ein Shellskript schreiben.
Nur wie ? (ich bin totaler noob)
Es muss auch in Unterverzeichnissen geaendert werden...

Es wuerde schon helfen ersteinmal alle eintraege zu aendern die mit
[\"] anfangen.

Es waere nett wenn mir jemand dabei helfen wuerde dieses Skript auszuformulieren.
 
Wie gewünscht, der Einzeiler ;)

Code:
find . -type f -exec perl -pi -e '~s/(?<![\w_\-@#.])subdomain.domainname.org/neu-subdomain.domainname.org/g' {} \;

Gruss, Phorus
 
Zuletzt bearbeitet:
Die Perlloesung wird IMHO verlaesslicher sein da inline-editing nicht bei allen sed-Derivaten supportet ist (inline-editing = editieren direkt in der Datei ohne temporaere Datei zu erstellen). Ich denke das ist der -i Schalter (arbeite hauptsaechlich mit sed unter Solaris, dort isses bei Standard-SED auf Solaris 8 nicht moeglich inline zu arbeiten).
 
whitey schrieb:
Hallo ihr lieben,

der Einzeiler ist ja schon echt super.
Ich hab ein aehnliches Problem, aber ich glaube nicht das man es in eine Zeile packen kann.

Die Zeile...
Code:
 perl -pi -e '~s|subdomain\.domainname\.org|neu-subdomain\.domainname\.org|' *

...wandelt mir meinen String wie gewuenscht um.
subdomain.domainname.org wird umbenannt in neu-subdomainname.org

Leider wird aber auch...
neusubdomain.domainname.org umbenannt in
neu-neusubdomainname.org

Und da ist der haken. Ich muss alle ascii zeichen ausklammern vor dem subdomain.domain.org jedoch steht vor dem subdomain.domain.org of ein " , / , : oder leerzeichen die erlaubt sein soll. Wobei wir beim dem anscheinend sehr beliebten Thema Regular Expressions waeren .

Soweit hab ich mich schon schlau gemacht
[^0-9a-zA-Z] vor subdomain.domain.org sollen verboten sein.
fuer Grep also [[:alnum:]]
Die restlichen moeglichen Zeichen die evtl zu erwarten waeren und eine Aenderung ausschliessen sollen:
- _ @ # .
[[:alnum]_-\@\#\.]

Also muss ich ein Shellskript schreiben.
Nur wie ? (ich bin totaler noob)
Es muss auch in Unterverzeichnissen geaendert werden...

Es wuerde schon helfen ersteinmal alle eintraege zu aendern die mit
[\"] anfangen.

Es waere nett wenn mir jemand dabei helfen wuerde dieses Skript auszuformulieren.

Hallo
Sorry, aber so recht klar ist mir nicht was du willst.
Erster Hinweis:
[\"] beschreibt die Zeichenklasse für zwei Zeichen! Matcht auf Backslash ( \ ) oder Dobblequota ( " ) , was du wahrscheinlich nicht willst.
In Zeichenklassen bleiben alle Zeichen unescapet als solche erhalten. Ausnahme ist nur ] und - ( was nicht am Ende stehen darf.)
Suchst du also nach einem String der mit " beginnt und mit einem weiteren " endet (also zwischen "bal fasel " steht, dann wäre das etwa so:
Um den ersten zwischen doppelten Anführungszeichen stehenden String rauszuschnedein:
~s/^["]([^"].*?)["].*/$1/g
Zweiter Hinweis:
Bring doch mal ein paar Beispieldaten und das entsprechen gewünschte.

[[:alnum:]_-@#.] Diese Zeichen sollen nicht ersetzt werden, wenn sie wo stehen?

Lass also mal ein paar Infos mehr sehen, dann kann ich eventuell helfen.
Gruß Wolfgang
 
Phorus schrieb:
Wie gewünscht, der Einzeiler ;)

Code:
find . -type f -exec perl -pi -e '~s/(?<![\w_\-@#.])subdomain.domainname.org/neu-subdomain.domainname.org/g' {} \;

Gruss, Phorus

Ähm will ja nicht altklug sein, aber das matcht unter Umständen zu viel weg, (greedy-modus) ;)
Code:
find . -type f -exec perl -pi -e '~s/(?<![\w_\-@#.][b].*?[/b])subdomain[b]\.[/b]domainname[b]\.[/b]org/neu-subdomain.domainname.org/g' {} \;
Auch könnte es wahrscheinlicher sein, dass noch ein \s vor der subdomain stehen muss ( muss aber nicht sein, auch wenn es wahrscheinlich ist) dann würde ich davor noch \b bringen.

Nur so als Gedankenspielerei
:D
Gruß Wolfgang
PS Der Punkt muss natürlich escapet werden.
 
Zuletzt bearbeitet:
Wolfgang_1 schrieb:
Ähm will ja nicht altklug sein, aber das matcht unter Umständen zu viel weg, (greedy-modus) ;)
...

Hast recht. Danke, wieder was gelernt :)

Gruss, Phorus
 
!w0w!

Mein lieber Herr Gesangsverein, in der Windowswelt haette ich dazu ein 350kb Tool mit Adware bekommen...
Vielen lieben Dank.
(Kannst du die Adware auch noch in diese Zeile haemmern ??? ;) )


Waere es vermessen zu fragen ob ich dabei noch was lernen darf ?

Mal sehen ob ich das richtig verstehe.
Also mit find . werden alle Dateien angefasst .... auch die in den Unterverzeichnissen.
Mit -type f wird sichergestellt das er keine Verzeichnisse selbst ausgibt, nur files.
-exec perl (perl ausfuehren zur weiterverarbeitung des Ergebnisses)
-pi (Ausgabe und inline editing mit backup da noch... )
-e (... extension folgt) (Ich weiss allerdings nicht was das -e nun exact bedeutet.)
'~s| stream -> pipe ? richtig ?
( Das ganze in Klammern, weil es eine Bedingung darstellt ?
?<![\w_ Zeichen ist nicht w oder _ (sehr nett, www kommt auch haeufig vor... )
\-@#. und auch nicht - @ # oder .
) Klammer zu ...
subdomain.domainname.org/neu-subdomain.domainname.org/g Da wird nun gearbeitet. Aber ich verstehe nicht ganz warum dort nun '/' verwendet werden statt Pipes '|'.
g' {} \ Damit weiss ich nun gar nix anzufangen...

EDITH sagt: Da nun andere noch schneller sind und ich noch Probleme mit meinen ersten Tests hatte, nehm ich ein bisschen von dem Lob zurueck... aber nur ein bisschen. Auf jeden Fall wuerd ich aber gern wissen was da passiert,... :think: ;)
 
Zuletzt bearbeitet:
Wolfgang_1 schrieb:
Lass also mal ein paar Infos mehr sehen, dann kann ich eventuell helfen.
Gruß Wolfgang

Huhu Wolfgang,

danke fuer deine Hilfe und die Erklaerungen dazu.

Hier ein paar Beispiele:

vorher: http://subdomain.domainname.org
nachher: http://neu-subdomain.domainname.org

vorher: **********
nachher: **********

vorher: <!-- ##subdomain.domainname.org
nachher: <!-- ##neu-subdomain.domainname.org

vorher: Hallo subdomain.domainname.org
nachher: Hallo neu-subdomain.domainname.org

vorher: "subdomain.domainname.org"
nachher: "neu-subdomain.domainname.org"

vorher: url='subdomain.domainname.org'
nachher: url='neu-subdomain.domainname.org'

vorher: www.domainname.org
nachher: www.domainname.org

vorher: "www.beispieldomain.domainname.org"
nachher: "www.beispieldomain.domainname.org"

vorher: subdomain domainname.org
nachher: subdomain domainname.org

Es gibt immerwieder Faelle in denen die subdomain nur als Beispiel genannt wird oder die Domain und Topleveldomain allein fuer sich stehen,...
Geaendert werden php Dateien in denen statische Links veraendert werden muessen.
 
Ich nochmal :(

Die zweite Variante von Wolfgang gibt bei mir folgende Fehlermeldung aus:

Code:
Variable length lookbehind not implemented in regex; marked by <-- HERE in m/(?<![\w_\-@#.].*?)subdomain\.domainname\.org <-- HERE / at -e line 1.
 
Zuletzt bearbeitet:
Hallo
Also wenn domainname.org
ein feststehender konstanter String ist, suchen wir alles was vor diesem getrennt durch einen Punkt steht.
Dabei wird subdomain auf der linken seite von einem Nichtwortzeichen (\W) begrenzt.
Versuchen wir es mal.
ich schreibe das der Übersichthalber mal etwas anders.
Code:
 for i in $( find /pfad -type f); do
      perl -pi"bak" -e '~s!^   #Stringanfang
      (.*?)               #irgendetwas (non-greedy) steht in $1
      ([^\W])+?        # gefolgt von keinem Wortzeichen steht in $2
      (\w+[^.].*?)     # gefolgt von subdomain wortzeichen bis zum punkt $3
      \.(domainname\.org)+?  #domainname.org steht in $4
       (.*)$!              #Rest bis zum Zeilenende $5
          !$1$2neu-$3.$4$5!ixg' $i #gefangene Werte einsetzen auf $i anwenden
               done
Die Optionen i -Nicht casesensitiv, g - global, x -extendet

Naja ungetestet und sicher noch nicht perfekt.
Ohne die Kommentare kann das alles Perlteil in eine Zeile, dann aber die Kommentare raus.

Gruß Wolfgang
Wer Fehler findet mag sie berichtigen, hab leider keine Zeit das jetzt noch zu testen, schau aber später nochmal rein
 

Ähnliche Themen

Skript last_login

Strings ersetzen

[PERL] Mit Regex kompletten String durchsuchen und ersetzen

CGI laesst sich nicht ausfuehren

VirtualBox rpm.run

Zurück
Oben