Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit
GELÖST

Komplette Ausgabe einer For -f Schleife in die gleiche Datei zurück

Frage Entwicklung Batch & Shell

Mitglied: mathe172

mathe172 (Level 1) - Jetzt verbinden

15.03.2011, aktualisiert 18.10.2012, 5970 Aufrufe, 12 Kommentare

Hallo zusammen!

Dank diesem hilfreichen Tipp sind meine Versuche, kurze und effiziente Batches zu schreiben, meiner Meinung nach noch erfolgreicher geworden
Nun wurde in letzter Zeit mehrmals nach einem Skript gefragt, das eine Datei Zeilenweise verarbeitet und die Zeile bei Bedarf verändert. Das ganze soll wieder in der Ausgangsdatei landen...

Nun war mein Ansatz vereinfacht so:
01.
@echo off 
02.
::Gesamte Ausgabe der Schleife umleiten 
03.
(for /f "usebackq delims=" %%A in ("Datei.txt") do echo.%%A)>"Datei.txt"
Dieser Code sollte ja eigentlich jede Zeile von "Datei.txt" ausgeben und das alles wieder in die Datei schreiben.
Nun kommt aber die Fehlermeldung: Datei wurde nicht gefunden. -Seltsamerweise ist die Datei aber trotzdem leer, als ob die For-Schleife die Datei nicht findet, die Umleitung aber schon.

Da ich bis jetzt immer zu einer Temporären Datei gezwungen war, wollte ich wissen ob es an mir, der cmd.exe, der Programmunlogik oder am (wahrscheinlich) bekifften Programmierer liegt.
Vielleicht steht die Erklärung ja schon in dem oben genannten Beitrag und ich finde sie nicht.

Ich hoffe ihr wisst mehr
Mit freundlichen Grüßen,
Mathe172
Mitglied: Highend01
15.03.2011 um 21:42 Uhr
Die Umleitung braucht die Datei nicht zu "finden", es legt sie schlicht und ergreifend an / überschreibt sie bei jedem Scriptdurchlauf.

Wie hattest du es dir bitte vorgestellt, zeilenweise Daten aus einer Datei auszulesen, die schon vor der Ausgabe der ersten Zeile wieder überschrieben wird (und damit 0 Inhalt hat)??
Bitte warten ..
Mitglied: bastla
15.03.2011, aktualisiert 18.10.2012
@Highend01
Der Plan wäre es ja, zunächst (in der Klammer) alle Zeilen auszulesen und auszugeben, und erst danach die Ausgangsdatei mit dem "Gesamtergebnis" zu überschreiben (der Link http://www.administrator.de/wissen/schleife-ohne-mehrmaliges-%c3%96ffne ... ist oben bei "diesem" leicht zu übersehen) ...

@mathe172
Wäre tatsächlich eleganter als das klassische
01.
move "Datei.txt" %temp%\Datei.txt 
02.
for /f "delims=" %%A in (%temp%\Datei.txt) do >>"Datei.txt" echo %%A 
03.
del %temp%\Datei.txt
oder (leerzeilenbewahrend)
01.
move "Datei.txt" %temp%\Datei.txt 
02.
for /f "tokens=1* delims=:" %%A in ('findstr /n "^" %temp%\Datei.txt') do >>"Datei.txt" echo.%%B 
03.
del %temp%\Datei.txt
bzw
01.
move "Datei.txt" %temp%\Datei.txt 
02.
(for /f "tokens=1* delims=:" %%A in ('findstr /n "^" %temp%\Datei.txt') do echo.%%B)>"Datei.txt" 
03.
del %temp%\Datei.txt
Grüße
bastla

[Edit] Fehlerhafte Schreibweise von "%temp%\Datei.txt" korrigiert [/Edit]
Bitte warten ..
Mitglied: Highend01
15.03.2011 um 22:03 Uhr
@bastla

"und erst danach" beschreibt ja schon den eigentlichen Ansatz, das Ganze über eine temporäre Datei zu lösen. Dies wurde hier "vergessen" und deshalb funktioniert seine Herangehensweise ja auch nicht. Völlig unabhängig davon, ob er jetzt die Zieldatei immer neu geöffnet + geschrieben hätte (per >>) oder in einem Rutsch übertragen wollte

Du hast übrigens einen kleinen Schreibfehler in deinem Beispiel drin (nicht, dass es übernommen wird und dann die Frage gestellt wird, warum es nicht läuft):

01.
('findstr /n "^" %temp%\Datei.txt')
Bitte warten ..
Mitglied: mathe172
15.03.2011 um 22:08 Uhr
Hallo zusammen,
Erst mal danke für die Antworten!
Dies wurde hier "vergessen" und deshalb funktioniert seine Herangehensweise ja auch nicht.
Kannst du das bitte erklären? Wieso funktioniert jetzt die extrem-Kruzform nicht?

Mathe172
Bitte warten ..
Mitglied: bastla
15.03.2011 um 22:09 Uhr
@Highend01
Danke für's genaue Hinsehen - ich korrigier's oben ...
Vielleicht schaust Du Dir aber trotzdem den verlinkten Tipp von PH an, um zu erkennen, was die Grundidee von mathes Ansatz war ...

Grüße
bastla
Bitte warten ..
Mitglied: Highend01
15.03.2011 um 22:12 Uhr
Zitat von bastla:
Vielleicht schaust Du Dir aber trotzdem den verlinkten Tipp von PH an, um zu erkennen, was die Grundidee von mathes Ansatz war

Hatte ich getan. Deshalb hatte ich ja noch mal drauf geantwortet.

@mathe172

Weil deine Ein- und Ausgabedatei übereinstimmen. Verwende eine temporäre Datei für das Auslesen / alt. Schreiben.
Bitte warten ..
Mitglied: jeb-the-batcher
15.03.2011 um 22:20 Uhr
Hallo,

so einfach ist es dann auch wieder nicht.

Genau genommen würde das Konstrukt von mathe0815 dazu führen, dass die Datei neu erzeugt wird, dann aber Zeile für Zeile die Daten angehängt werden.

Aber wie schon erkannt klappt das nicht.

Erstaunlicherweise scheint es an sich auch egal zu sein, dass sich der Inhalt der Datei ändert, die Datei scheint gecached zu werden!
Sprich, es können Daten gelesen werden die gar nicht mehr da sind.

Test mit
01.
@echo off 
02.
( for /l %%n in (1,1,3) do echo %%n) > t.txt 
03.
 
04.
rem for %%a in (1) DO ( 
05.
for /F "delims=" %%b in (t.txt) DO 	( 
06.
	echo fileOut=%%b 
07.
	>con echo aktuelle Zeile "%%b" 
08.
	>con echo - Kompletter Inhalt von t.txt ---- 
09.
	>con type t.txt 
10.
	>con echo - Datei ende ---- 
11.
	>con echo( 
12.
) > t.txt 
13.
 
14.
--- OUTPUT ---- 
15.
 
16.
aktuelle Zeile "1" 
17.
- Kompletter Inhalt von t.txt ---- 
18.
fileOut=1 
19.
- Datei ende ---- 
20.
 
21.
aktuelle Zeile "2" 
22.
- Kompletter Inhalt von t.txt ---- 
23.
fileOut=2 
24.
- Datei ende ---- 
25.
 
26.
aktuelle Zeile "3" 
27.
- Kompletter Inhalt von t.txt ---- 
28.
fileOut=3 
29.
- Datei ende ----
Nur leider klappt es eben nicht mehr, wenn man die ganze For-Schleife in einen Block packt.

Gruß
jeb
Bitte warten ..
Mitglied: Biber
15.03.2011 um 22:50 Uhr
Moin,

ich weiss zwar nicht genau, was denn das erhoffte Einsparpotential sein soll, andererseits .... wird ja bestimmt für einen guten Zweck sein.
Und ist bestimmt besser, als irgendwo rumzuhängen...

Wieso findet ihr das Verhalten denn absonderlich?
Wenn eine Umleitung mit einer Pipe (also hier dem ">"-Zeichen) verlangt wird, dann wird zuerst das Ziel als Filehandle geöffnet,
und dabei eine 0-Byte-Datei im Verzeichnis angelegt, bevor überhaupt irgendeine Ausgabe zu schreiben ist.

Einfacher zum Nachvollziehen:
  • Macht einfach zwei CMD-Fenster auf, lasst beide im Standardverzeichnis stehen
  • ruft in einem die Sleep.exe auf mit einem für Langsamtipper angemessenen Wert, z.B 20 oder 200 [sec] und leitet das Ergebnis um
01.
sleep 20>sleeptest.txt
Im anderen Fenster macht ihr ein
01.
dir sleept*.* 
02.
... 
03.
15.03.2011  22:41                 0 sleeptest.txt
...die Datei ist da, LANGE bevor da irgendein Output kommen könnte... die SLEEP.exe ist immer noch am Rumwarten.

Und dieses "Umleitungsziel wird zuerst angelegt"-Verhalten erklärt doch die Mathe-Frage zur Genüge, oder?

Wie sollte es denn auch anders sein?
Eine andere "Reihenfolge" wäre doch fatal.
Angenommen, eine 10-Gigabyte-Datei sollte per "type monsterlog.txt" umgeleitet werden auf "eineReadonlyDatei.txt".
Soll zuerst der "Type monsterlog.txt" vollständig durchrödeln, auch wenn er den Output im Ziel nicht schreiben kann?

Oder auch hier ein einfaches Beispiel:
[Das führende ">" gehört zum CMD-Prompt - nicht mit Eintippseln]
01.
>echo x >readonly.txt 
02.
 
03.
(=22:57:03  D:\temp=) 
04.
>attrib readonly.txt +r 
05.
 
06.
(=22:57:07  D:\temp=) 
07.
>dir c:\  /s /b >readonly.txt 
08.
Zugriff verweigert
....und er führt NICHT zuerst den kompletten DIR-Liste-mir-2-Millionen-Dateien-auf aus, sondern öffnet erst das Ziel "readonly.txt" oder verreckt.

Grüße
Biber
Bitte warten ..
Mitglied: bastla
15.03.2011 um 22:58 Uhr
[OT]
@Biber
ich weiss zwar nicht genau, was denn das erhoffte Einsparpotential sein soll
... hybsch wär's gewesen (und da ja die 10-Gigabyte-Text-Dateien doch noch nicht soo überhandnehmen dürften, könnten sich die die paar GB RAM auch einmal nützlich machen) ...

Grüße
bastla
[/OT]
Bitte warten ..
Mitglied: Biber
15.03.2011 um 23:13 Uhr
[noch OTiger]
@bastla

Wenn meine geheimsten Hoffnungen in Erfüllung gehen...
und Karl Theodor zu Guttenberg tatsächlich Goldbärchens Nachfolger wird und "Wetten dass.." moderiert....

-> dann werde ich ihm ein paar Kandidaten nennen, die mit einer Querflöte 10 Schokopuddings in einer Minute durch einen Heuballen blasen können.
Oder zumindest ähnliches vorturnen .

Grüße zurück
Biber
[/noch OTiger]
Bitte warten ..
Mitglied: pieh-ejdsch
15.03.2011 um 23:27 Uhr
moin,

Wenn eine Umleitung mit einer Pipe (also hier dem ">"-Zeichen) verlangt wird, dann wird zuerst das Ziel als Filehandle geöffnet,
genau das wollte ich auch gerade schreiben

normal kommt ja auch ein Fehler, wenn eine bestimmte Datei nicht existiert, aber wenn die Zeile eingelesen wird und eine Datei lesegeschützt zum Schreiben geöffnet wird - wird diese in diesem Moment auch erstellt und ist auch vorhanden bei der ausführung der Batch-/CMDZeile.
aber als kleinen test im CMD:
if exist "%temp%\testdatei.txt" del "%temp%test\datei.txt" 
type "%temp%\testdatei.txt" 
 
type "%temp%\testdatei.txt">"%temp%\tesdatei.txt" 
type "%temp%\testdatei.txt"
wegen der einzelumleitung des kompletten Befehles ist es ja so, das zu Beispiel:
type nul>D:\testdatei.txt 
(for /l %i in (1,1,100000) do @echo.)>D:\testdatei.txt
bei mir ~ 5 sekunden dauerte, aber
type nul>D:\testdatei.txt 
for /l %i in (1,1,100000) do @echo.>>D:\testdatei.txt
~ 1 min 45 sek dauerte

Zeitmessung über Batchdatei
das kann ich mir nur erklären das beim 1. mal die Datei nur 1 mal geöffnet und abschliesend geschlossen wird -> schprich ein Schreibzugriff
beim zweiten mal hingegen wird die Datei 100.000 mal geöffnet und auch genausoviel mal wieder geschlossen - abgesehne von den Lese-/Schreibzugriffen in der MFT

was allerdings die Forschleife von Jeb macht kann ich nicht erklären.

Gruß Phil
Bitte warten ..
Mitglied: mathe172
16.03.2011 um 13:33 Uhr
Hallo zusammen,
ich danke euch für die vielen Antworten!
Ich mach mal den Haken hin, da die Anfangsfrage ja gelöst wurde.

Vielleicht lässt sich Jeb's Schleife ja so erklären:
ForSchleife:Datei einlesen und zwischenspeichern
Klammer nach do: Ganze Klammer wird umgeleitet, also t.txt neu erstellen
echo-Befehl: Nichts anderes Angegeben, also nach t.txt
type-Befehl:Datei einlesen und ausgeben
Nächster Durchgang (ab Klammer nach Do)

Dagegen war mein Versuch:
Klammer vor For: Ganze Klammer wird umgeleitet, also Datei.txt neu erstellen
ForSchleife:Datei einlesen und zwischenspeichern-->Findet nichts, keine Schleifendurchgänge
-->nicht steht mehr in der Datei

Danke nochmal,
Mathe172
Bitte warten ..
Neuester Wissensbeitrag
DSL, VDSL

Telekom blockiert immer noch den Port 7547 in ihrem Netz

(3)

Erfahrungsbericht von joachim57 zum Thema DSL, VDSL ...

Ähnliche Inhalte
IDE & Editoren
USB STICK Datei AUTOMATISCH beim anschliessen auf fremden PC öffnen (9)

Frage von Jwanner83 zum Thema IDE & Editoren ...

Batch & Shell
Batch-Variable nach Stichworten aus TXT Datei durchsuchen (3)

Frage von Markus5579 zum Thema Batch & Shell ...

VB for Applications
gelöst Bestimmte Spalten aus CSV-Datei auslesen (VBS) (9)

Frage von Gurkenhobel zum Thema VB for Applications ...

Heiß diskutierte Inhalte
Windows Userverwaltung
Ausgeschiedene Mitarbeiter im Unternehmen - was tun mit den AD Konten? (34)

Frage von patz223 zum Thema Windows Userverwaltung ...

LAN, WAN, Wireless
gelöst Server erkennt Client nicht wenn er ausserhalb des DHCP Pools liegt (28)

Frage von Mar-west zum Thema LAN, WAN, Wireless ...

LAN, WAN, Wireless
FritzBox, zwei Server, verschiedene Netze (21)

Frage von DavidGl zum Thema LAN, WAN, Wireless ...

Viren und Trojaner
Aufgepasst: Neue Ransomware Goldeneye verbreitet sich rasant (20)

Link von Penny.Cilin zum Thema Viren und Trojaner ...