none
Im Verzeichnis Textdateien finden und diese bearbeiten RRS feed

  • Frage

  • Win 7; PowerShell 4,0

    Hallo liebe Leut',

    bin Laie und bin vor kurzem über ein privates Projekt auf PowerShell gestossen.

    Möchte in einem Verzeichnis mit Unterverzeichnisse Textdateien finden und diese bearbeiten. Im Einzelnen laufen diese.

    Aber wie kann ich die 2 Befehle verbinden?

    Im Einzelnen lauten sie so:

    gci $Path -recurse | ?{$_.Name -like '*nfo'}

    Diesen Befehl wollte ich nun mit folgendem Befehl verbinden:

    (Get-Content $Path) |
    Foreach-Object {$_ -replace $althttp, $neu} |
    Set-Content $Path |

    Für Eure Mühe möchte ich mich im Voraus bedanken und verbleibe mit

    LG

    Svensus

    Montag, 16. Februar 2015 11:30

Antworten

  • Hallo,

    zum Beispiel so:

    $Path = 'E:\temp'
    $AltStr = 'xxx'
    $NeuStr = 'yyy'
    foreach ($File in (Get-ChildItem -Path $Path -Filter '*nfo' -file -Recurse | Select-Object -ExpandProperty FullName)) {
    	(Get-Content $File) | ForEach-Object { $_ -replace "$AltStr", "$NeuStr" | Set-Content $File }
    }

    Ich habe mal den Ansatz gewaehlt, weil man hier die gleichzeitige Verwendung der beiden unterschiedlichen Foreach Sprachelemente  sieht, die die Powershell kennt.

    Als Hinweis, es ist immer sinnvoll so weit wie moeglich links zu filtern >gci $Path -recurse | ?{$_.Name -like '*nfo'}<, also nicht erst alle gefundenen Dateien in die Pipe zu schmeissen und dann erst zu filtern, den das kann der get-childitem, ueber seinen -filter Parameter schneller. Auch ist es glaube ich zu mindest ratsam auf Aliase wie gci zu verzichten, zumindest als Anfaenger.

    Beste Gruesse
    brima



    Montag, 16. Februar 2015 15:18
  • Hallo Svensus,

    die Antwort von brima finde ich ebenfalls gut, wenn du willst kannst du es aber auch mit diesem Lösungsweg versuchen:

    Get-Childitem $Path -recurse -Filter *nfo | ForEach-Object {(Get-Content $Path\$_ | ForEach-Object {$_ -replace "$alt","$neu"}) | Set-Content $Path\$_}

    Es ist wichtig dass du auf die Klammern achtest, vorallem auf den Unterschied von geschwungen und normal.

    $Path spiegelt den kompletten Pfad OHNE Datei wieder, die zurzeit gewählte Datei wird durch $_ wiedergegeben.

    Wenn ich fragen darf, wieso benötigst du die Befehle als Einzeiler? Ein kleines Skript fände ich übersichtlicher/schöner.

    LG

    Freeman





    Dienstag, 17. Februar 2015 12:53

Alle Antworten

  • Hallo,

    zum Beispiel so:

    $Path = 'E:\temp'
    $AltStr = 'xxx'
    $NeuStr = 'yyy'
    foreach ($File in (Get-ChildItem -Path $Path -Filter '*nfo' -file -Recurse | Select-Object -ExpandProperty FullName)) {
    	(Get-Content $File) | ForEach-Object { $_ -replace "$AltStr", "$NeuStr" | Set-Content $File }
    }

    Ich habe mal den Ansatz gewaehlt, weil man hier die gleichzeitige Verwendung der beiden unterschiedlichen Foreach Sprachelemente  sieht, die die Powershell kennt.

    Als Hinweis, es ist immer sinnvoll so weit wie moeglich links zu filtern >gci $Path -recurse | ?{$_.Name -like '*nfo'}<, also nicht erst alle gefundenen Dateien in die Pipe zu schmeissen und dann erst zu filtern, den das kann der get-childitem, ueber seinen -filter Parameter schneller. Auch ist es glaube ich zu mindest ratsam auf Aliase wie gci zu verzichten, zumindest als Anfaenger.

    Beste Gruesse
    brima



    Montag, 16. Februar 2015 15:18
  • Hallo Svensus,

    die Antwort von brima finde ich ebenfalls gut, wenn du willst kannst du es aber auch mit diesem Lösungsweg versuchen:

    Get-Childitem $Path -recurse -Filter *nfo | ForEach-Object {(Get-Content $Path\$_ | ForEach-Object {$_ -replace "$alt","$neu"}) | Set-Content $Path\$_}

    Es ist wichtig dass du auf die Klammern achtest, vorallem auf den Unterschied von geschwungen und normal.

    $Path spiegelt den kompletten Pfad OHNE Datei wieder, die zurzeit gewählte Datei wird durch $_ wiedergegeben.

    Wenn ich fragen darf, wieso benötigst du die Befehle als Einzeiler? Ein kleines Skript fände ich übersichtlicher/schöner.

    LG

    Freeman





    Dienstag, 17. Februar 2015 12:53
  • Hallo Freeman und Brima,

    danke für Deine Antwort.

    Meine hat gedauert, weil das beantworten auf Themen mit dem Firefox-Browser nicht funktioniert.

    Jetzt gehe ich halt mit dem IE ins Netz, was mir nicht gefällt. Was soll es.

    Werde Deinen Weg mal jetzt auch mal ausprobieren.

    LG

    Svensus

    Samstag, 21. Februar 2015 19:48
  • Hi,

    habe jetzt mal die Lösungen probiert, hier sind Fehler aufgetreten

    Vielleicht hätte ich bessere Angaben machen müssen. Die Struktur sieht in etwa so aus, die Textdateien stehen in den folgenden Verzeihnissen:

    Verzeichnis 1 + Datei1.nfo
    Verzeichnis 2 + Datei2.nfo
    Verzeichnis 3 + Datei3.nfo

    In den Textdateien gibt es viele Textzeilen, enthalten ist aber auch dieser String (?): <Image/Ich wechsle öfter meinen Namen>

    Nun soll in allen .nfo-Dateien dieser String ersetzt werden.

    $alt = "<Image*"
    $Neu = "Ich bin beständig"

    $Path = 'C:\Users\Test'

    $AltStr = "<Image*"
    $NeuStr = "Ich bin beständig"
    $Path = 'C:\Users\Test'
    
    foreach ($File in (Get-ChildItem -Path $Path -Filter '*nfo' -file -Recurse | Select-Object -ExpandProperty FullName)) {
    	(Get-Content $File) | ForEach-Object { $_ -replace "$AltStr", "$NeuStr" | Set-Content $File }
    }
    
    

    Dieser Befehle von Brima führte dazu, dass alles in den Textdateien gelöscht wurde.

    Und mit dem folgenden Befehl von Freeman, bekam ich eine Fehlermeldung mit Abbruch (es hatet sich in den Text-Dateien nichts geändert)

    Get-Childitem $Path -recurse -Filter *nfo | ForEach-Object {(Get-Content $Path\$_ | ForEach-Object {$_ -replace "$alt","$neu"}) | Set-Content $Path\$_}

    Könnt Ihr mir bitte weiterhelfen?

    LG

    Svensus

    Donnerstag, 12. März 2015 14:33
  • Hallo,

    dann musst Du genauer beschreiben was Du willst, wieso taucht zb.: jetzt hier > $AltStr = "<Image*" < der Stern auf. Was willst Du damit bezwecken? Ich glaube der Stern arbeitet nicht so wie du dir das vorstellst. Kannst ja mal beide folgende Code Abschnitte testen.

    $Text = 'AAA <Image/Ich wechsle öfter meinen Namen> ZZZ'
    $AltStr = "<Image*"
    $NeuStr = "Ich bin beständig"
    $Text -replace "$AltStr", "$NeuStr"
    
    #
    
    $Text = 'AAA <Image/Ich wechsle öfter meinen Namen> ZZZ'
    $AltStr = "Ich wechsle öfter meinen Namen"
    $NeuStr = "Ich bin beständig"
    $Text -replace "$AltStr", "$NeuStr"

    Beste Gruesse

    brima

    Donnerstag, 12. März 2015 15:31
  • Hallo,

    und das mein Code "zuviel ersetzt" liegt an einer verschobenen Klammer, ich bin mir eigenlich ziemlich sicher das ich das korrigiert hatte, aber egal, hier noch mal der Code.

    $Path = 'E:\temp'
    $AltStr = 'xxx'
    $NeuStr = 'yyy'
    foreach ($File in (Get-ChildItem -Path $Path -Filter '*nfo' -file -Recurse | Select-Object -ExpandProperty FullName)) {
    	(Get-Content $File) | ForEach-Object { $_ -replace "$AltStr", "$NeuStr" } | Set-Content $File 
    }

    Donnerstag, 12. März 2015 15:49
  • Hallo Brima,

    Du gehst ganz richtig in der Annahme, das ich mit
    $AltStr = "<Image*" ==> das Sternchen als Wildcard betrachtet habe,
    und dies ergab dann das Ergebnis, wie Du es Dir gedacht hast. "<Image" wurde gelöscht und mit dem Rest aufgefüllt.

    Bin grad am Lernen, immer wenn ich denke, das ist es, dann muss ich fest stellen, dass ich Euch
    nicht die notwendigen Daten gegeben habe und meine Ergebnisse falsch sind.

    Gibt es an dieser Stelle überhaupt die Möglichkeit von Wildcards?

    Denn es sollte eigentlich so vonstatten gehen.

    In den verschiedenen .nfo - Dateien stehen mehrere unterschiedliche Textzeilen.
    Ich wollte alle die Zeilen ersetzen welche so anfangen:

    <thumb>http://image.tmdb.org........(hier stehen immer unterschiedliche Angaben)...........jpg</thumb>

    Mein Ziel war es ab <thumb> mit einer bestimmten Pfadangabe zu ersetzen. Also damit:
    "M:\Film\Bilder\Ich bin ein Star.jpg</thumb>"

    Das Ergebnis sollte dann in allen .nfo-Dateien so aussehen:
    <thumb>M:\Film\Bilder\Ich bin ein Star.jpg</thumb>

    Sorry für meine Fehler.
    But nobody is perfect.

    LG
    svensus

    Donnerstag, 12. März 2015 18:08
  • Hallo svensus,

    ich befuerchte dass Du immer noch nicht alle Karten auf den Tisch gelegt hast.

    Natuerlich kann man auch mit Wildcards arbeiten, aber in komplexerer Form. Nennt sich Regulaere Ausdruecke (RegEx). Zu dem Thema alleine gibt es eigene Buecher ...
    Ich bin kein Fachmann fuer regulaere Ausdruecke und es ist auch schwierig gescheite Pattern (Schablonen) zu bauen, wenn man die Daten die du ersetzen willst nicht kennt. :-(

    Also dein Beispiel kannst Du z.B.: so bearbeiten.

    '<thumb>http://image.tmdb.org........(hier stehen immer unterschiedliche Angaben)...........jpg</thumb>' -replace '(<thumb>).*(</thumb>)', '$1M:\Film\Bilder\Ich bin ein Star.jpg$2'

    Das Ergbenis waere dann:

    <thumb>M:\Film\Bilder\Ich bin ein Star.jpg</thumb>

    '<thumb>Jetzt steht hier aneres Zeug</thumb>' -replace '(<thumb>).*(</thumb>)', '$1M:\Film\Bilder\Ich bin ein Star.jpg$2'

    ergibt dann ebenso:

    <thumb>M:\Film\Bilder\Ich bin ein Star.jpg</thumb>

    Ich kann mit aber nicht so recht vorstellen, das du das willst, sondern wenn ich deine Infos richtig deute willst aus der WEB-URL fuer die Bilder Dateipfade bauen?

    '<thumb>http://image.tmdb.org/dasErsteBild.jpg</thumb>' -replace '(<thumb>).*/(.*\.jpg)(</thumb>)', '$1M:\Film\Bilder\$2$3'

    macht

    <thumb>M:\Film\Bilder\dasErsteBild.jpg</thumb>

    '<thumb>http://image.tmdb.org/deep2/deep3/nocheinbild.jpg</thumb>' -replace '(<thumb>).*/(.*\.jpg)(</thumb>)', '$1M:\Film\Bilder\$2$3'

    macht

    <thumb>M:\Film\Bilder\nocheinbild.jpg</thumb>

    Ich hoffe das bringt dich in die richtige Richtung, jetzt im Deatail auf RegEX einzugehen macht keinen Sinn. Es gibt auch zahlreiche Seiten zu dem Thema.

    Beste Gruesse
    brima

    Donnerstag, 12. März 2015 18:52
  • Wow,

    Hallo Brima,

    ich bin wirklich beeindruckt, was für eine Mühe Du Dir machst, um jeden nach bestem Wissen zu helfen.

    Ich möchte mich auch für die schnelle Hilfe bedanken.

    Das Ergebnis entspricht genau meinen Anforderungen.
    Es klappt nun mit dem 1. Befehl, die weiteren habe ich nicht probiert.

    .....-replace '(<thumb>).*(</thumb>)', '$1M:\Film\Bilder\Ich bin ein Star.jpg$2'

    LG
    svensus

    Freitag, 13. März 2015 12:07