FOR Schleifen in Perl?

Guten Tag

In einer CSV Datei steht z.B.:

ABC_YXZ[0];
ABC_YXZ[1];
ABC_YXZ[2];
ABC_YXZ[3];
ABC_YXZ[4];
ABC_YXZ[?];

Nun will ich nicht mit ABC_YXZ[0] sondern mit ABC_YXZ[13] beginnen.

ABC_YXZ[13];
ABC_YXZ[14];
ABC_YXZ[15];
ABC_YXZ[16];
ABC_YXZ[17];
ABC_YXZ[??];

Folgenden Perl-Script Suchen/Ersetzen Ansatz habe ich gefunden (getestet):

perl -i.bak -pe "s/ABC/DEF/g" test.csv

Hat soweit gut funktioniert, ist aber nicht die Lösung.

Mit meinen minimalen C Kenntnissen denke ich natürlich gleich an eine FOR Schleife in der man den Such-String und Ersatz-String zusammensetzt usw.

Wie stelle ich das mit Perl an?

Grüsse, Olli

PS:

D:\tmp\perl\>perl -v

This is perl, v5.10.0 built for MSWin32-x86-multi-thread
(with 1 registered patch, see perl -V for more detail)

Copyright 1987-2007, Larry Wall

Binary build 1001 [283495] provided by ActiveState http://www.ActiveState.com
Built Dec 18 2007 08:46:15

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

Hallo,

In einer CSV Datei steht z.B.:

ABC_YXZ[0];
ABC_YXZ[1];
ABC_YXZ[2];
ABC_YXZ[3];
ABC_YXZ[4];
ABC_YXZ[?];

Nun will ich nicht mit ABC_YXZ[0] sondern mit ABC_YXZ[13]
beginnen.

ABC_YXZ[13];
ABC_YXZ[14];
ABC_YXZ[15];
ABC_YXZ[16];
ABC_YXZ[17];
ABC_YXZ[??];

Folgenden Perl-Script Suchen/Ersetzen Ansatz habe ich gefunden
(getestet):

perl -i.bak -pe „s/ABC/DEF/g“ test.csv

Hat soweit gut funktioniert, ist aber nicht die Lösung.

Mit meinen minimalen C Kenntnissen denke ich natürlich gleich
an eine FOR Schleife in der man den Such-String und
Ersatz-String zusammensetzt usw.

Wie stelle ich das mit Perl an?

Also die Option -p baut implizit eine Schleife, die ueber alle Zeilen iteriert.

Prinzipiell brauchst du auch ein search and replace, also ist s/// schon richtig.

Es gibt da noch einen Trick, und zwar wenn du hinten ein e anhaengst (also s///e), dann wird die zweite Haelfte nicht als string, sondern als perl-Program interpretiert. Damit kannst du sowas machen:

perl -pe ‚s/[(\d+)]/"[" . ($1 + 13) . „]“/e‘ test.csv

(Wenn der Code machst, was du willst, kannst du das -i fuer „in-place“ wieder einfuegen).

Was das macht ist: Sucht nach ‚[‘, gefolgt von mehreren ziffern, gefolgt von ‚]‘. Ersetzt den gefundenen Ausdruck durch [, der Ziffernfolge plus 13, gefolgt von einem].

HTH,
Moritz

Also die Option -p baut implizit eine Schleife, die ueber alle
Zeilen iteriert.

Prinzipiell brauchst du auch ein search and replace, also ist
s/// schon richtig.

Es gibt da noch einen Trick, und zwar wenn du hinten ein e
anhaengst (also s///e), dann wird die zweite Haelfte nicht als
string, sondern als perl-Program interpretiert. Damit kannst
du sowas machen:

perl -pe ‚s/[(\d+)]/"[" . ($1 + 13) . „]“/e‘ test.csv

(Wenn der Code machst, was du willst, kannst du das -i fuer
„in-place“ wieder einfuegen).

Was das macht ist: Sucht nach ‚[‘, gefolgt von mehreren
ziffern, gefolgt von ‚]‘. Ersetzt den gefundenen Ausdruck
durch [, der Ziffernfolge plus 13, gefolgt von einem].

HTH,
Moritz

Hallo Moritz

Vielen Dank für Deine Antwort. Ich aheb das Script ausprobiert, aber:

D:\tmp\perl\>perl -pe 's/\[(\d+)\]/"[" . ($1 + 13) . "]"/e' test.csv
Can't find string terminator "'" anywhere before EOF at -e line 1.

Dann habe habe ich nachgesehen was -e bedeutet:

D:\tmp\perl\>perl -h

Usage: C:\Perl\bin\perl.exe [switches] [--] [programfile] [arguments]
 -0[octal] specify record separator (\0, if no argument)
 -a autosplit mode with -n or -p (splits $\_ into @F)
 -C[number/list] enables the listed Unicode features
 -c check syntax only (runs BEGIN and CHECK blocks)
 -d[:debugger] run program under debugger
 -D[number/list] set debugging flags (argument is a bit mask or alphabets)
 -e program one line of program (several -e's allowed, omit programfile)
 -E program like -e, but enables all optional features
 -f don't do $sitelib/sitecustomize.pl at startup
 -F/pattern/ split() pattern for -a switch (//'s are optional)
 -i[extension] edit files in place (makes backup if extension supplied)
 -Idirectory specify @INC/#include directory (several -I's allowed)
 -l[octal] enable line ending processing, specifies line terminator
 -[mM][-]module execute "use/no module..." before executing program
 -n assume "while () { ... }" loop around program
 -p assume loop like -n but print line also, like sed
 -P run program through C preprocessor before compilation
 -s enable rudimentary parsing for switches after programfile
 -S look for programfile using PATH environment variable
 -t enable tainting warnings
 -T enable tainting checks
 -u dump core after parsing program
 -U allow unsafe operations
 -v print version, subversion (includes VERY IMPORTANT perl info)
 -V[:variable] print configuration summary (or a single Config.pm variable)
 -w enable many useful warnings (RECOMMENDED)
 -W enable all warnings
 -x[directory] strip off text before #!perl line and perhaps cd to directory
 -X disable all warnings 

Hmm, wird da irgend ein EOF oder EOL falsch interpretiert. Ist dass das selbe Problem wie mit Text-Files die auf Linux erzeugt und unter Windows geöffnet werden und dann alles auf einer Zeile erscheint?

Beste Grüsse

Olli

perl -pe ‚s/[(\d+)]/"[" . ($1 + 13) . „]“/e‘ test.csv

D:\tmp\perl>perl -pe ‚s/[(\d+)]/"[" . ($1 + 13) .
„]“/e‘ test.csv
Can’t find string terminator „’“ anywhere before EOF at -e
line 1.

… ich habs:

D:\tmp\perl\>perl -pe "s/\[(\d+)\]/'[' . ($1 + 13) . ']'/e" test.csv
ABC\_XYZ[13];
ABC\_XYZ[14];
ABC\_XYZ[15];
ABC\_XYZ[16];
ABC\_XYZ[17];
ABC\_XYZ[18];
ABC\_XYZ[19];

… ich muss " und ’ vertauschen …?! Und mit i.bak funktioniert es dann besten.

Vielen Dank nochmal an Moritz

Olli

Hallo,

… ich muss " und ’ vertauschen …?! Und mit i.bak
funktioniert es dann besten.

Ja, weil das shell-escaping under windows und linux unterschiedlich funktioniert (und ich mein Script unter Linux getestet habe).

Gruesse,
Moritz