tiforst
Goto Top

Texteil anhand zweier Vorgaben aus Datei löschen

Grüßt euch,

ich habe mich hier angemeldet, da ich folgendes Problem habe:

Ich möchte gerne aus sämtlichen Dateien mit der Endung .dat bestimmte Inhalte löschen. Diese beginnen immer mit <meta type="Keywords"> und enden mit </meta>. <meta type="Keywords"> und </meta> sollen dabei ebenfalls gelöscht werden. Der Inhalt ist allerdings immer unterschiedlich lang und befindet sich an unterschiedlichen stellen und die Dateien befinden sich kreuz und quer auf dem Rechner verteilt. Läßt sich das durch eine Batch oder Powershell lösen oder benötige ich dazu spezielle Software? Wenn ja, welche?

Danke fürs Reinschauen

tiforst

Content-Key: 315119

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

Printed on: May 4, 2024 at 14:05 o'clock

Member: TlBERlUS
TlBERlUS Sep 13, 2016 at 09:27:23 (UTC)
Goto Top
Moin,


Zitat von @tiforst:
Ich möchte gerne aus sämtlichen Dateien mit der Endung .dat bestimmte Inhalte löschen. Diese beginnen immer mit <meta type="Keywords"
soll die gesamte Zeile gelöscht werden, in der Das Keyword ist?
die Dateien befinden sich kreuz und quer auf dem Rechner verteilt.
Heißt auch im Windows-Verzeichnis, oder in den Userordnern, etc.?
Läßt sich das durch eine Batch oder Powershell lösen oder benötige ich dazu spezielle Software? Wenn ja, welche?
Jup
Danke fürs Reinschauen
Bitte

Grüße,

Tiberius
Member: tiforst
tiforst Sep 13, 2016 at 09:41:33 (UTC)
Goto Top
Hallo Tiberius,

es kann vorkommen, dass vor <meta type="Keywords"> oder nach </meta> noch Einträge vorhanden sind. Von daher sollte am Besten nur der Inhalt, nicht aber die Zeile gelöscht werden, auch wenn daraus resultierend evtl. leere Zeilen entstehen.

Die Dateien befinden sich nicht im Systemordner. Es wäre Klasse wenn sich das Rootverzeichnis anpassen lassen könnte, z.b. X:/data/ da auch externe Datenträger betroffen sind.

Schon einmal Danke im Voraus

tiforst
Member: Friemler
Friemler Sep 13, 2016 at 20:31:16 (UTC)
Goto Top
Hallo tiforst,

anhand Deiner Beschreibung vermute ich mal, dass Deine *.dat Dateien Daten im XML-Format enthalten. Ist das richtig?

Grüße
Friemler
Member: tiforst
tiforst Sep 14, 2016 at 05:36:56 (UTC)
Goto Top
Hallo Friemler

ja die Dateiinhalte sind im XML-Format. Ich habe auch nochmals nachgesehen und der zu löschende Bereich steht tatsächlich alleine in einer eigenen Zeile. Nur beim öffenen im Editor stand alles in einer Zeile.
Member: TlBERlUS
TlBERlUS Sep 14, 2016 updated at 10:42:00 (UTC)
Goto Top
Teste diesen Code einmal:
clear-host
$source = "C:\Users\test\Desktop\Test"  
$files = gci -recurse  $source |?{$_.Extension -eq ".dat"}   
$search = '<meta type="Keywords">'  

foreach ($f in $files){
    $content = gc $source\$f
    $newcontent = @()
    foreach($c in $content){
        if ($c -notlike "*$search*"){  
            $newcontent += $c
        }    
    }
    Set-Content $source\$f  $newcontent
}
Edit: Recure-Suche eingefügt
Edit2: Wegen Bearbeitungsrichtlinien ist das aktualisierte Skript weiter unten
Member: Friemler
Friemler Sep 14, 2016 updated at 09:17:01 (UTC)
Goto Top
Hallo tiforst,

ich würde für die Bearbeitung einer XML-Datei eher den Weg über das dafür vorgesehene ActiveX-Objekt gehen, den Microsoft XML DOM Parser. Das verhindert auch Probleme mit der Codierung der XML-Datei (Windows 1252, ISO 8859-X, UTF-8, UTF-16 und was es sonst noch so gibt).

@echo off & setlocal

set "VBScript=%TEMP%\DeleteMetaNode.vbs"  

> "%VBScript%" echo.Dim objXmlDoc, colNodes, objNode, strFile  
>>"%VBScript%" echo.  
>>"%VBScript%" echo.If WScript.Arguments.Count ^> 0 Then  
>>"%VBScript%" echo.  strFile = WScript.Arguments(0)  
>>"%VBScript%" echo.  
>>"%VBScript%" echo.  Set objXmlDoc   = CreateObject("Microsoft.XMLDOM")  
>>"%VBScript%" echo.  objXmlDoc.async = False  
>>"%VBScript%" echo.  
>>"%VBScript%" echo.  objXmlDoc.load(strFile)  
>>"%VBScript%" echo.  
>>"%VBScript%" echo.  If objXmlDoc.parseError.errorCode = 0 Then  
>>"%VBScript%" echo.    Set colNodes = objXmlDoc.documentElement.selectNodes("//meta")  
>>"%VBScript%" echo.  
>>"%VBScript%" echo.    For Each objNode In colNodes  
>>"%VBScript%" echo.      objNode.parentNode.removeChild(objNode)  
>>"%VBScript%" echo.    Next  
>>"%VBScript%" echo.  
>>"%VBScript%" echo.    objXmlDoc.save(strFile)  
>>"%VBScript%" echo.  End If  
>>"%VBScript%" echo.End If  

if "%~1" neq "" (  
  set "RootFolder=%~1"  
) else (
  set "RootFolder=."  
)

for /r "%RootFolder%" %%a in (*.dat) do (  
  echo Verarbeite %%a
  cscript /nologo "%VBScript%" "%%a"  
)

del "%VBScript%" > NUL  


Wenn Du das Script z.B. als DeleteMetaNodes.cmd speicherst, kannst Du es folgendermaßen starten:
DeleteMetaNodes "RootFolder"
wobei RootFolder der Pfad des Verzeichnisses ist, bei dem das Script starten soll rekursiv nach *.dat Dateien zu suchen. Wird dieser Parameter weggelassen, startet das Script beim aktuellen Verzeichnis.

Grüße
Friemler
Member: tiforst
tiforst Sep 14, 2016 at 10:22:23 (UTC)
Goto Top
Hallo Tiberius,

Danke Dir. das funktioniert sehr gut. Allerdings nur in dem einen Ordner, der unter source angegeben wird, nicht in dessen Unterordnern. Ließe sich das noch einfügen?

Grüße

tiforst
Member: tiforst
tiforst Sep 14, 2016 at 10:26:56 (UTC)
Goto Top
Hallo Friemler,

vielen Dank für deinen Vorschlag. Lieder möchte es nicht so wie es soll. Das bearbeiten der einzelnen Dateien dauert sehr lange und die zu löschende Zeile ist immernoch vorhanden.

Grüße

tiforst
Member: TlBERlUS
TlBERlUS Sep 14, 2016 at 10:36:43 (UTC)
Goto Top
Zitat von @tiforst:
Danke Dir. das funktioniert sehr gut. Allerdings nur in dem einen Ordner, der unter source angegeben wird, nicht in dessen Unterordnern. Ließe sich das noch einfügen?
Jup, habe den oberen Code angepasst. Sollte jetzt klappen.
Member: TlBERlUS
Solution TlBERlUS Sep 14, 2016 at 10:41:13 (UTC)
Goto Top
Ich durfte den Quelltext nicht mehr nachträglich ändern.
clear-host
$source = "C:\Users\test\Desktop\Test"  
$files = gci -recurse  $source |?{$_.Extension -eq ".dat"}   
$search = '<meta type="Keywords">'  

foreach ($f in $files){
    $filepath = $f.DirectoryName
    
    $content = gc $filepath\$f
    $newcontent = @()
    foreach($c in $content){
        if ($c -notlike "*$search*"){  
            $newcontent += $c
        }    
    }
    Set-Content $filepath\$f  $newcontent
}
Mitglied: 129813
129813 Sep 14, 2016 updated at 10:55:09 (UTC)
Goto Top
XML Files are preferred modified by using an XML parser and XPath selection, or XSLT, like @Friemler already suggested!
gci 'C:\Users\test\Desktop\Test' -recurse -Filter *.dat | %{  
    $xml = [xml](gc $_.Fullname)
    if ($xml){
        $xml.SelectNodes("//meta[@type='Keywords']")| %{$_.ParentNode.RemoveChild($_)}  
        $xml.Save($_.Fullname)
    }
}
Regards
Member: Friemler
Friemler Sep 14, 2016 at 13:15:27 (UTC)
Goto Top
Hallo tiforst,

kann ich nicht nachvollziehen, das Script läuft hier einwandfrei, die Dateien werden geändert. Kann dann nur daran liegen, dass Deine Eingabedateien kein valides XML enthalten. Um das festzustellen müsstest Du mal eine (evtl. verkürzte) Beispieldatei hier posten. Sensible Daten kannst Du dazu ausmaskieren.

Grüße
Friemler