randolph
Goto Top

Problem mit FINDSTR und Pfeil-nach-links Zeichen

Hallo allerseits!

Ich habe ein Problem mit folgendem Progrämmchen:

@echo off
SETLOCAL enabledelayedexpansion
FOR /f "delims=" %%i IN (inputfile.txt) DO (
SET textline=%%i
echo !textline! | findstr SearchString
)
ECHO Done^^!

Wenn in der zu durchsuchenden Datei (inputfile.txt) das Zeichen "<" vorkommt, dann erzeugt das folgende Fehlermeldung:
"Das System kann die angegebene Datei nicht finden"
Wir wohl irgendwie als Redirector interpretiert...

Hat jemand eine Lösung für dieses Problem?
Bin sehr dankbar für Anregungen.

Danke+viele Grüsse
Randolph

Content-Key: 217488

Url: https://administrator.de/contentid/217488

Ausgedruckt am: 29.03.2024 um 06:03 Uhr

Mitglied: bastla
bastla 20.09.2013 aktualisiert um 20:38:06 Uhr
Goto Top
Hallo Randolph und willkommen im Forum!

Was hast Du denn genau vor (denn nur zum Ausgeben der passenden Zeilen würdest Du ja einfach
findstr SearchString inputfile.txt
verwenden face-wink)?

Grundsätzlich könntest Du das ansonsten etwa so versuchen:
echo !textline! | findstr SearchString >nul && echo !textline!
Grüße
bastla

P.S.: Bitte zum Posten von Code die passende Formatierung einsetzen ...
Mitglied: Randolph
Randolph 20.09.2013 um 21:30:43 Uhr
Goto Top
Hallo bastla,

Danke für die schnelle Antwort!
hoffe ich hab das verstanden wie das mit der Formatierung funtioniert. Hier mal ein Test:

ECHO off
SETLOCAL enabledelayedexpansion
FOR /f "delims=" %%i IN (inputfile.txt) DO (  
SET textline=%%i
echo !textline! | findstr SearchString
)
ECHO Done^^!

Hab meine Anwendung so weit wie möglich minimiert, damit jeder schnell sehen kann um was es geht.

In meiner Anwendung will ich in der Datei inputfile.txt bei den Zeilen, welche den SearchString enthalten die Zeilenenden (ab der Position des SearchStrings) durch einen festen Text ersetzen. Und da ich diese Fehlermeldungen bekomme kann ich nicht sicher sein, dass das Ersetzen in allen Fällen richtig funktioniert.
Ohne Fehlermeldungen wär mir schon lieber.

viele Grüsse
Randolph
Mitglied: Endoro
Endoro 20.09.2013 um 23:18:31 Uhr
Goto Top
Hi,
das Problem ist die Pipe |, da bleiben die Sonderzeichen hängen.
Mein Vorschlag (case-insensitiv):
@ECHO OFF &SETLOCAL
FOR /f "delims=" %%i IN (inputfile.txt) DO (  
	SET "textline=%%i"  
	SETLOCAL ENABLEDELAYEDEXPANSION
	if "!textline!" neq "!textline:SearchString=!" echo(!textline!  
	ENDLOCAL
)
ECHO Done!
Bei dieser Technik der Forschleife werden übrigens alle Leerzeilen eliminiert.
lg.
Mitglied: bastla
bastla 20.09.2013 aktualisiert um 23:45:41 Uhr
Goto Top
Hallo Randolph!

Zur Unterscheidung, ob eine Zeile bearbeitet werden muss oder unverändert ausgegeben werden kann, lässt sich der oben gezeigte Ansatz verwenden:
echo !textline! | findstr SearchString >nul && (
    echo !textline! bearbeiten
) || (
    echo !textline! unveraendert ausgeben
)
- schematisch dann also etwa so:
@ECHO off
set "SearchString=DeinString"  
set "FixText=DeinZusatz"  
set "Ausgabe=DeineDatei.txt"  

SETLOCAL enabledelayedexpansion
(FOR /f "delims=" %%i IN (inputfile.txt) DO (  
    SET "textline=%%i"  
    echo "!textline!" | findstr "%SearchString%">nul && (  
        set "Teil2=!textline:*%SearchString%=!"  
        call set "textline=%%textline:!Teil2!=%FixText%%%"  
    )
    echo !textline!
))>"%Ausgabe%"  
ECHO Done^^!
Falls auch der SearchString selbst ersetzt werden soll, müsste die Zeile 10 so aussehen:
call set "textline=%%textline:%SearchString%!Teil2!=%FixText%%%"
Grüße
bastla
Mitglied: Randolph
Randolph 22.09.2013 um 11:11:55 Uhr
Goto Top
Hallo zusammen,

vielen Dank für die Beiträge, hat mich schon einee Schritt weitergebracht.

@bastla: Da dein Code pipes verwendet fürchte ich, dass mir die "<"-Zeichen in dem zu parsenden inputfile wieder in die Quere kommen.

Also habe ich erst mal auf dem Vorschlag von Endoro aufgesetzt. Funktioniert soweit, Problem mit "<"-Zeichen ist weg.

Beim nächsten Schritt hakt es aber wieder: Die Startposition des Suchstrings in der Zeile ermitteln.

Ich hab dazu eine Routine im Web gefunden, die ohne pipes auskommt, allerdings bekomme ich mit dem folgenden code keinen Positionswert zurück:

@ECHO off 
SETLOCAL

SET "searchstring1=CONTACT_FORMAT"  

FOR /f "delims=" %%i IN (inputfile.txt) DO (  
	SET "textline=%%i"  
	SETLOCAL enabledelayedexpansion
	if "!textline!" neq "!textline:%searchstring1%=!" (  
		CALL :findString "!textline!" %searchstring1% position  
		echo The last position of "CONTACT" in the line is %pos%	  
		) ELSE (
		REM Do nothing
		)
	ENDLOCAL
)
GOTO :ENDE

:findString -- returns position of first occurrence of a string in another string
::          -- %~1: in - varible name of a string to be searched
::          -- %~1: in - string to be found
::          -- %~3: out- return variable name, will be set to position or undefined if string not found

SETLOCAL ENABLEDELAYEDEXPANSION
set "pos="  
set "str=!%~1!"  

for /L %%a in (0,1,1023) do (
   set "s=!str:~%%a!"  
   if not defined pos if "%~2!s:*%~2=!"=="!s!" set "pos=%%a"  
)
ENDLOCAL (
IF "%~3" NEQ "" SET "%~3=%pos%"  
)
GOTO:EOF

:ENDE
ECHO Done^^!

Mir ist auch nicht klar, warum in der Subroutine die Variablennamen mit Tilde verwendet werden: %~3 (statt %3).
Kann mir das jemand erklären?

Ich hab das also wieder vereinfacht, um rauszukriegen was da schief läuft:

@ECHO off 
SETLOCAL

SET "searchstring1=CONTACT_FORMAT"  
set pos=100

FOR /f "delims=" %%i IN (inputfile.txt) DO (  
	SET "textline=%%i"  
	SETLOCAL enabledelayedexpansion
	if "!textline!" neq "!textline:%searchstring1%=!" (  
		CALL :findString 15 34 %pos%
		echo The last position of "CONTACT_FORMAT": %pos%  
		) ELSE (
		REM Do nothing
		)
	ENDLOCAL
)
GOTO :ENDE

:findString -- returns position of first occurrence of a string in another string, case sensitive, maximum string length is 1023 characters
::          -- %~1: in - varible name of a string to be searched
::          -- %~1: in - string to be found
::          -- %~3: out- return variable name, will be set to position or undefined if string not found
SETLOCAL ENABLEDELAYEDEXPANSION
set var1=%1
set var2=%2
set var3=%3
set %3=199
echo %var1% and %var2% and %var3%
ENDLOCAL (
set %3=199
)
GOTO:EOF

:ENDE
ECHO Done^^!

Die Variable pos bzw. auch %3 in der Subroutine bleiben immer auf dem Wert 100. Der Wert 199 wird nie übernommen face-sad
Bin jetzt wieder am Ende mit meinem Latein. Kann mir jemand einen Tip geben ?

Wär klasse !

Danke+Grüsse
Randolph
Mitglied: bastla
bastla 22.09.2013 um 13:45:06 Uhr
Goto Top
Hallo Randolph!
fürchte ich, dass mir die "<"-Zeichen in dem zu parsenden inputfile wieder in die Quere kommen.
Du ziehst Befürchtungen einem Test vor?

Grüße
bastla
Mitglied: Randolph
Randolph 22.09.2013 um 23:21:00 Uhr
Goto Top
Hallo bastla,

du hast völlig recht. Du hast dir die Mühe gemacht und die Antwort plus Code dazu verfasst, dann sollte ich das zumindest mal antesten.
Habe einfach der Antwort von Endoro Glauben geschenkt, dass das Problem mit den pipes zusammenhängt.
Da habe ich dein Lösung erst mal verworfen, weil diese pipes benutzt.

Ich glaube inzwischen, dass es mit der String-Substitution zusammenhängt und eher nicht mit den pipes.
Was meinst du dazu ?

Auf jeden Fall habe ich jetzt nach einigen Stunden rumprobieren ein Progrämmchen, welches genau das tut was ich will und welches ich der Vollständigkeit halber hier poste.
Es ersetzt Zeilenenden von Zeilen, die einen bestimmten Suchstring enthalten mit einem definierbaren Fixtext.
Es benutzt keine pipes und auch keine CALL-Aufrufe.

@ECHO off 
SETLOCAL
echo Starte Fakturama auf deutsch
SET "fakturama_workdir=D:\Daten\Fakturama\Database\"  
SET "fakturama_progdir=C:\Programme\Fakturama\"  
SET "quell_datei=Database.script"  
SET "ziel_datei=Database.script.tmp"  
SET "searchstring4='CONTACT_FORMAT_GREETING_COMMON',"  
SET "searchstring3='CONTACT_FORMAT_GREETING_MR',"  
SET "searchstring2='CONTACT_FORMAT_GREETING_MS',"  
SET "searchstring1='CONTACT_FORMAT_GREETING_COMPANY',"  
SET "replacement4='Sehr geehrte Damen und Herren')"  
SET "replacement3='Sehr geehrter Herr {lastname}')"  
SET "replacement2='Sehr geehrte Frau {lastname}')"  
SET "replacement1='Sehr geehrte Damen und Herren')"  

REM Loeschen der Ausgabedatei, falls sie (noch) existiert
IF EXIST %ziel_datei% (DEL /f %ziel_datei% 1>NUL 2>NUL)

FOR /f "delims=" %%i IN (%fakturama_workdir%%quell_datei%) DO (  
	SET "textline=%%i"  
	SETLOCAL enabledelayedexpansion
	IF "!textline!" neq "!textline:%searchstring1%=!" (  
		call set rest=%%textline:*!searchstring1!=%%
		call set anfang=%%textline:!rest!=%%
		set NeueZeile=!anfang!!replacement1!
		ECHO !NeueZeile!>>%ziel_datei%
		) ELSE (
				IF "!textline!" neq "!textline:%searchstring2%=!" (  
				call set rest=%%textline:*!searchstring2!=%%
				call set anfang=%%textline:!rest!=%%
				set NeueZeile=!anfang!!replacement2!
				ECHO !NeueZeile!>>%ziel_datei%
				) ELSE (
						IF "!textline!" neq "!textline:%searchstring3%=!" (  
						call set rest=%%textline:*!searchstring3!=%%
						call set anfang=%%textline:!rest!=%%
						set NeueZeile=!anfang!!replacement3!
						ECHO !NeueZeile!>>%ziel_datei%
						) ELSE (
							IF "!textline!" neq "!textline:%searchstring4%=!" (  
							call set rest=%%textline:*!searchstring4!=%%
							call set anfang=%%textline:!rest!=%%
							set NeueZeile=!anfang!!replacement4!
							ECHO !NeueZeile!>>%ziel_datei%
							) ELSE (
								REM Write original line
								ECHO !textline!>>%ziel_datei%
									))))							
ENDLOCAL
)
DEL %fakturama_workdir%%quell_datei%
REN %fakturama_workdir%%ziel_datei% %quell_datei%	
START %fakturama_progdir%Fakturama.exe -nl de_DE

Die Frage, warum das "<"-Zeichen Probleme bei FINDSTR bzw. Stringsubstitution macht ist allerdings noch nicht geklärt.
Deshalb weiss ich nicht, ob man das Thema auf gelöst setzen kann.

Wie setzt man denn ein Thema auf gelöst und wer macht das üblicherweise?

Vielen Dank und viele Grüsse
Randolph
Mitglied: Endoro
Endoro 23.09.2013 um 00:12:45 Uhr
Goto Top
Hi Randolph,
Zitat von @Randolph:
Die Frage, warum das "<"-Zeichen Probleme bei FINDSTR bzw. Stringsubstitution macht ist allerdings noch nicht
geklärt.
Weil die Schutzfunktion von delayed expansion sich nicht auf die Pipe erstreckt.
Deshalb müssen dann die gefährlichen Sonderzeichen <>&| wieder escaped werden.
Entweder wie @bastla es gemacht hat ("ZollZeichen") oder ^Carets^.

Wie setzt man denn ein Thema auf gelöst und wer macht das üblicherweise?
Das macht üblicherweise der Threadstarter. Wie steht in der FAQ face-smile
lg.