dusselmann
Anmeldungsdatum: 6. Mai 2005
Beiträge: 1055
|
Hallo zusammen, ich brauche ein Bash-Script, welches aus einer CSV-Datei Werte ausliest (2 Spalten pro Zeile) und dann ein Verzeichnis nach Dateiinhalten mit dem Wort aus der ersten Spalte sucht und dieses Wort mit dem Wort aus Spalte 2 ersetzt. Folgendes hab ich schon gefunden: cat $1 > /dev/null
while read LINE
do
search=`echo $LINE | cut -d ";" -f1`
replace=`echo $LINE | cut -d ";" -f2 | cut -d " " -f1`
for i in $2
do
sed -i 's/$search/$replace/g' $i
done
done < $1 Würde das funktionieren? Geht es auch "eleganter"? Brauche dringend Hilfe! Danke schon mal! Gruß, Dussel
|
audax
Anmeldungsdatum: 15. September 2006
Beiträge: 1253
|
Machs nicht in der Bash. Nein. Nein. Nein. Schonmal daran gedacht, was das Script bei
foo;bar;fo\;obaz tut?
|
MrKanister
Anmeldungsdatum: 13. Oktober 2007
Beiträge: 2105
|
Hallo,
cat $1 > /dev/null Ws bringt das?
for i in $2
do
sed -i 's/$search/$replace/g' $i
done sed verändert nur den Puffer, nicht die Dateien. Lies besser den Namen der Datei komplett ein. ($ALTER_NAME) dann veränder ihn mit sed nach deinen Vorstellungen (so wie dus mit sed schon vorhattest) und speicher den Namen in einer neuen Variable ($NEUER_NAME). Dann benutzt zum umbennen "mv"
mv "$ALTER_NAME" "$NEUER_NAME" done < $1 Mit welchen Parametern willst du dein Skript starten? Wenn du den Pfad der CSV-DAtei mit angeben willst, dann mach
done < cat "$1" for i in $2 In $2 sollen also die Namen aller Dateien sein, auf die der Name zutrifft? Nimm besser eine while-Schleife (auch wegen möglichen Leerzeichen)
find /PFAD/ZU/DEN/DATEIEN -name "${search}*" | while read ZEILE ...und dann wie gesagt mit "mv" Wenn du noch genaueres brauchst, einfach melden 😉 Gruß Martin
|
comm_a_nder
Anmeldungsdatum: 5. Februar 2006
Beiträge: 2533
Wohnort: Dresden
|
audax hat geschrieben: Machs nicht in der Bash. Nein. Nein. Nein. Schonmal daran gedacht, was das Script bei
foo;bar;fo\;obaz tut?
Mit welchen programmiersprachlichen Mittel würdest Du solch ein kapottes csv bearbeiten?
|
comm_a_nder
Anmeldungsdatum: 5. Februar 2006
Beiträge: 2533
Wohnort: Dresden
|
Mr. Kanister hat geschrieben:
for i in $2
do
sed -i 's/$search/$replace/g' $i
done sed verändert nur den Puffer, nicht die Dateien. Lies besser den Namen der Datei komplett ein. ($ALTER_NAME) dann veränder ihn mit sed nach deinen Vorstellungen (so wie dus mit sed schon vorhattest) und speicher den Namen in einer neuen Variable ($NEUER_NAME).
Du willst mal nachschauen, was -i bei sed bewirkt ... 😉
|
comm_a_nder
Anmeldungsdatum: 5. Februar 2006
Beiträge: 2533
Wohnort: Dresden
|
meine adhoc Lösung (ohne jegliche Fehlerprüfungen und ohne es getestet zu haben):
while read LINE
do
sed_command=$(echo "$LINE" | awk -F';' '{print "s/"$1"/"$2"/g"}')
find "$2" -type f -exec sed -e $sed_command {} \;
done < "$1"
|
dusselmann
(Themenstarter)
Anmeldungsdatum: 6. Mai 2005
Beiträge: 1055
|
comm_a_nder hat geschrieben: meine adhoc Lösung (ohne jegliche Fehlerprüfungen und ohne es getestet zu haben):
while read LINE
do
sed_command=$(echo "$LINE" | awk -F';' '{print "s/"$1"/"$2"/g"}')
find "$2" -type f -exec sed -e $sed_command {} \;
done < "$1"
herrje, sieht kompliziert aus. wie gesagt, ich möchte die dateien nicht umbenennen, sondern deren inhalte manipulieren. das hab ich jetzt:
while read LINE
do
search=`echo $LINE | cut -d ";" -f1`
echo rv search $LINE: $search $?
replace=`echo $LINE | cut -d ";" -f2 | cut -d " " -f1`
echo rv replace $LINE: $replace $?
for i in $(find . -type f -name "$2" )
do
sed -i "s/$search/$replace/g" $i
echo rv sed $i: $?
done
done < $1 das funktioniert auch, bis auf: er liest nur 1 (von 2) dateien ein und ändert diese. die 2. berührt er nicht. warum?
|
audax
Anmeldungsdatum: 15. September 2006
Beiträge: 1253
|
comm_a_nder hat geschrieben: audax hat geschrieben: Machs nicht in der Bash. Nein. Nein. Nein. Schonmal daran gedacht, was das Script bei
foo;bar;fo\;obaz tut?
Mit welchen programmiersprachlichen Mittel würdest Du solch ein kapottes csv bearbeiten?
Auch bei csv kann man mit dem Backslash Zeichen escapen. Ich würd Python/Perl nehmen.
|
dusselmann
(Themenstarter)
Anmeldungsdatum: 6. Mai 2005
Beiträge: 1055
|
audax hat geschrieben: Ich würd Python/Perl nehmen.
ich brauche es als bash script
|
comm_a_nder
Anmeldungsdatum: 5. Februar 2006
Beiträge: 2533
Wohnort: Dresden
|
audax hat geschrieben:
Auch bei csv kann man mit dem Backslash Zeichen escapen. Ich würd Python/Perl nehmen.
Probier es mal bitte in Python oder Perl, hab gerade keine Gelegenheit dazu. Der csv Import in OpenOffice zB versagt bei Deinem Beispiel
|
dusselmann
(Themenstarter)
Anmeldungsdatum: 6. Mai 2005
Beiträge: 1055
|
so, es funktioniert: while read LINE
do
search=`echo $LINE | cut -d ";" -f1`
echo rv search $LINE: $search $?
replace=`echo $LINE | cut -d ";" -f2 | cut -d " " -f1`
echo rv replace $LINE: $replace $?
for i in $(find . -type f -name "$2" )
do
sed -i "s/$search/$replace/g" $i
echo rv sed $i: $?
done
done < $1
|
audax
Anmeldungsdatum: 15. September 2006
Beiträge: 1253
|
comm_a_nder hat geschrieben: audax hat geschrieben:
Auch bei csv kann man mit dem Backslash Zeichen escapen. Ich würd Python/Perl nehmen.
Probier es mal bitte in Python oder Perl, hab gerade keine Gelegenheit dazu. Der csv Import in OpenOffice zB versagt bei Deinem Beispiel
Da CSV kein echter Standard ist, sagt man den Python/Perl-Parsern einfach, welche Symbole escapen 😉
|
Afflux
Anmeldungsdatum: 5. Juni 2006
Beiträge: 119
Wohnort: Reiskirchen
|
audax hat geschrieben: Da CSV kein echter Standard ist, sagt man den Python/Perl-Parsern einfach, welche Symbole escapen 😉
RFC 4180
|
Sid_Burn
Anmeldungsdatum: 23. Oktober 2004
Beiträge: 2159
|
Also wie audax schon sagte sind CSV Dateien etwas kompliziertes und ein Reines Splitten ist nicht ganz Korrekt. Und ein Beispiel das auch out-of-the-boc mit OpenOffice.org läuft ist folgende zeile. David;Raab;"Perl; Programmierer";"Jetzt kann man "";"" im Datensatz nutzen";24 Das ganze obere Beispiel hat dann 5 Spalten anstatt 7 wie ein reines Splitt machen würde. und Funktioniert so auch in OpenOffice.org. Aber auch in OpenOffice.org kann man beim importieren angeben welches Zeichen als escape dient. In der Regel wenn im Datensatz allerdiengs das Trennsymbol vorkommt setzt man das ganze z.B. in Hochkommata. Soll ein Hochkommate im String vorkommen werden zwei aufeinanderfolgende Hochkommata genutzt um es zu escapen. Die obere Zeile ist so angepasst wie OpenOffice.org Default Arbeitet "Insert->Sheet From File" Man kann zwar eine Regex zusammenbauen die das auslesen kann (zumindest in Perl) aber viel Spaß dabei.... In Perl kann man dafür dann z.B. Text::CSV_XS nutzen. Afflux hat geschrieben: audax hat geschrieben: Da CSV kein echter Standard ist, sagt man den Python/Perl-Parsern einfach, welche Symbole escapen 😉
RFC 4180
Ein RFC ist kein Standard. 😉 RFC steht für "Request for Common" (anfrage nach einem Standard). Standards fangen mit STD an. Ansonsten ist eine RFC ja toll, wenn sich aber keiner daran hält was nunmal oft der Fall ist, und jeder andere Trennzeichen etc. nimmt dann bringt einem ein RFC Dokument auch nichts.
|
Afflux
Anmeldungsdatum: 5. Juni 2006
Beiträge: 119
Wohnort: Reiskirchen
|
Sid Burn hat geschrieben: Ein RFC ist kein Standard. 😉 RFC steht für "Request for Common" (anfrage nach einem Standard). Standards fangen mit STD an. Ansonsten ist eine RFC ja toll, wenn sich aber keiner daran hält was nunmal oft der Fall ist, und jeder andere Trennzeichen etc. nimmt dann bringt einem ein RFC Dokument auch nichts.
RFC steht für "Request for Comments" (anfordern von Kommentaren). However, auf Request for Comments steht: "Bei der ersten Veröffentlichung noch im ursprünglichen Wortsinne zur Diskussion gestellt, behalten RFC auch dann ihren Namen, wenn sie sich durch allgemeine Akzeptanz und Gebrauch zum Standard entwickelt haben." In diesem speziellen Fall fiel mir tatsächlich aber erst nachher auf, dass dieser RFC eher beschreibender als standardisierender Natur ist ("An attempt at a common definition", wie es in eben diesem o.g. Dokument steht). Edit: bevor du mir jetzt sagst, dass es trotzdem noch kein ISO/DIN/sonstwas Standard ist, das ist mir schon bewusst. Allerdings könnte man dann bei einigen Protokollen nicht von Standardisierung sprechen, und die "allgemeine Akzeptanz" ist IMHO eine de facto Standardisierung.
|