Powershell skript erweitert und will nicht

fanti67

Cadet 1st Year
Registriert
Mai 2023
Beiträge
14
Hallo,

ich habe ein Skript das funktioniert. Jetzt wollte ich es erweitern so das es automatisch alle .txt Dateien bearbeitet. Daran scheite ich.
die erste Zeile und die letzte sind hinzugekommen und für den Dateinamen habe ich $_.name genutzt. Den musste ich vorher mit übergeben. Leider finde ich den Fehler nicht. Die Zeilen zwischen der erste und letzten funktionieren schon und tuen was sie sollen.

die .txt Dateien liegen im selben Verzeichnis wie das Skript.

Hier das Skript:

Get-ChildItem "*.txt" | foreach-object {

$path1 = "C:\local\dateien\$_.name"
#Inputfile laden
$kurz = "c:\ziel2.txt"
$aufget = "c:\ziel3.txt"
$temp = "c:\temp.txt"

gc $path1 | where {$_ -ne ""} > c:\ziel.txt

$input = Get-Content C:\ziel.txt
$ip127 = $input

foreach($line in $ip127){

if($line -notlike '127.0.'){
echo $line >> $temp
}
}
$path = "c:\ziel.txt"
Remove-Item $path
ren $temp $path

$input = Get-Content C:\ziel.txt
$akti = $input

foreach($line in $akti){

if($line -notlike 'Aktive'){
echo $line >> $temp
}
}
Remove-Item $path
ren $temp $path

$input = Get-Content C:\ziel.txt
$proto = $input

foreach($line in $proto){

if($line -notlike 'Proto'){
echo $line >> $temp
}
}
Remove-Item $path
ren $temp $path

$input = Get-Content C:\ziel.txt
$ster = $input

foreach($line in $ster){

if (-not($line.Contains(':'))){
echo $line >> $temp
}
}
Remove-Item $path
ren $temp $path

$input = Get-Content C:\ziel.txt
$v6 = $input

foreach($line in $v6){

if($line -notlike '::'){
echo $line >> $temp
}
}
Remove-Item $path
ren $temp $path

$input = Get-Content C:\ziel.txt
$inter = $input

foreach($line in $inter){

if(-not($line.Contains('0.0.0.'))){
echo $line >> $temp
}
}
Remove-Item $path
ren $temp $path

$input = Get-Content C:\ziel.txt
foreach ($temp in $input)
{
$String = $temp
$zwischen = $String.Remove(0,32) | Out-file -FilePath $kurz -Append

}

$auft = Get-Content $kurz

foreach ($line in $auft)
{
$String = $line.Split(" ")
$zwischen = $String[0] | Out-file -FilePath $aufget -Append

}

Remove-Item $path1
Remove-Item $path
Remove-Item $kurz
Ren $aufget c:\$_.name
Move-Item -Path C:\$_.name -Destination C:\local\dateien

}
 
Zuletzt bearbeitet:
Ich soll dich von ChatGPT grüßen :P

Ich würde dir empfehlen, es zu benutzen um Zeit zu sparen und vorallem Nerven:

Output von Chatti:

Es gibt mehrere Fehler in deinem Skript. Hier sind einige der Probleme:

  1. In der Zeile $path1 = "C:\local\dateien\$.name" verwendest du $ außerhalb einer Schleife. Du musst dies in eine Schleife wie foreach oder ForEach-Object einbetten, damit $_ einen Wert hat.
  2. In den Zeilen, in denen du die Datei "ziel.txt" verarbeitest, hast du die Zeile Remove-Item $path vor der Zeile ren $temp $path. Dadurch wird die Datei "ziel.txt" gelöscht, bevor sie umbenannt wird. Du solltest die Reihenfolge umkehren, indem du ren $temp $path vor Remove-Item $path platzierst.
  3. In den Zeilen, in denen du die Datei "ziel.txt" verarbeitest, verwendest du immer den gleichen Speicherort $temp für temporäre Dateien. Das führt dazu, dass vorherige Ergebnisse überschrieben werden. Du musst für jede temporäre Datei einen eindeutigen Speicherort verwenden.
  4. In der Zeile $zwischen = $String.Remove(0,32) | Out-file -FilePath $kurz -Append verwendest du die Pipe (|) mit Out-File, um die Ausgabe in die Datei "$kurz" umzuleiten. Dies funktioniert in PowerShell nicht wie erwartet. Du solltest stattdessen den Befehl Add-Content verwenden, um den Inhalt an die Datei anzufügen.
  5. In der Zeile Ren $aufget c:\$.name möchtest du die Datei "$aufget" umbenennen und den Namen aus der Pipeline-Variable $ verwenden. Du musst die Verwendung von $_ in der Zeile anpassen, um den gewünschten Effekt zu erzielen. Eine Möglichkeit besteht darin, die Zeile in eine Schleife einzubetten, die $_ verwendet, wie zum Beispiel ForEach-Object.

Und hier die berichtigte Version: ( ich hab es ehrlich gesagt nicht getestet )

PowerShell:
Get-ChildItem "*.txt" | ForEach-Object {
    $path1 = "C:\local\dateien\$($_.Name)"
    $kurz = "c:\ziel2.txt"
    $aufget = "c:\ziel3.txt"
    $temp = "c:\temp.txt"

    Get-Content $path1 | Where-Object { $_ -ne "" } | Set-Content "c:\ziel.txt"

    $input = Get-Content "C:\ziel.txt"
    $ip127 = $input | Where-Object { $_ -notlike '127.0.*' }

    $ip127 | Set-Content $temp
    Remove-Item "C:\ziel.txt"
    Rename-Item $temp "c:\ziel.txt"

    $input = Get-Content "C:\ziel.txt"
    $akti = $input | Where-Object { $_ -notlike 'Aktive*' }

    $akti | Set-Content $temp
    Remove-Item "C:\ziel.txt"
    Rename-Item $temp "c:\ziel.txt"

    $input = Get-Content "C:\ziel.txt"
    $proto = $input | Where-Object { $_ -notlike 'Proto*' }

    $proto | Set-Content $temp
    Remove-Item "C:\ziel.txt"
    Rename-Item $temp "c:\ziel.txt"

    $input = Get-Content "C:\ziel.txt"
    $ster = $input | Where-Object { $_ -notlike '*:*' }

    $ster | Set-Content $temp
    Remove-Item "C:\ziel.txt"
    Rename-Item $temp "c:\ziel.txt"

    $input = Get-Content "C:\ziel.txt"
    $v6 = $input | Where-Object { $_ -notlike '*::*' }

    $v6 | Set-Content $temp
    Remove-Item "C:\ziel.txt"
    Rename-Item $temp "c:\ziel.txt"

    $input = Get-Content "C:\ziel.txt"
    $inter = $input | Where-Object { $_ -notlike '*0.0.0.*' }

    $inter | Set-Content $temp
    Remove-Item "C:\ziel.txt"
    Rename-Item $temp "c:\ziel.txt"

    $input = Get-Content "C:\ziel.txt"
    $input | ForEach-Object {
        $String = $_
        $zwischen = $String.Substring(32)
        Add-Content -Path $kurz -Value $zwischen
    }

    $auft = Get-Content $kurz
    $auft | ForEach-Object {
        $String = $_.Split(" ")
        $zwischen = $String[0]
        Add-Content -Path $aufget -Value $zwischen
    }

    Remove-Item $path1
    Remove-Item "C:\ziel.txt"
    Remove-Item $kurz
    Rename-Item $aufget "$($_.Name)"
    Move-Item -Path "C:\$($_.Name)" -Destination "C:\local\dateien"
}
 
Leider bekomme ich folgende Fehlermeldung:
Get-Content : Der Pfad "C:\local\dateien\ThirdPartyNoticesBySHS.txt" kann nicht gefunden werden, da er nicht vorhanden ist.
In C:\local\dateien\bereinigen3.ps1:7 Zeichen:5
  • Get-Content $path1 | Where-Object { $_ -ne "" } | Set-Content "c: ...
  • ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\local\dateie...oticesBySHS.txt:String) [Get-Content], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand

in dem Verzeichnis gibt es die Datei ThirdPartyNoticesBySHS.txt gar nicht.

Er übernimmt nicht den Namen der in Zeile 1 gefunden werden soll
 
fanti67 schrieb:
Hallo,

ich habe ein Skript das funktioniert. Jetzt wollte ich es erweitern so das es automatisch alle .txt Dateien bearbeitet. Daran scheite ich.
Hallo,

könntest du evtl. ersteinmal anständig Formulieren was du mit dem Script überhaupt machen willst?
Dein Code liest sich echt grausig.

Das Nächste, benutzte doch bitte die Code ansicht für deinen Code, das macht das lesen wesentlich angenehmer.
 
ColdGlow schrieb:
Ich soll dich von ChatGPT grüßen :p
danke
Ergänzung ()

Das Skript nimmt eine Datei und entfernt alle unerwünschten Zeilen um sie dann wieder unter dem Originalnamen zu speichern.
es werden Zeilen mit folgenden Inhalten gelöscht:
127.0.
0.0.0.
Leerzeilen
Proto
Aktive
* : *
::
Ergänzung ()

sikarr schrieb:
benutzte doch bitte die Code ansicht für deinen Code
wie geht das?
 
Zuletzt bearbeitet:
fanti67 schrieb:
1683790670920.png
 
hier noch einmal der Code:

Code:
Get-ChildItem "*.txt" | foreach-object {

$path1 = "C:\local\dateien\$_.name"
#Inputfile laden
$kurz = "c:\ziel2.txt"
$aufget = "c:\ziel3.txt"
$temp = "c:\temp.txt"

gc $path1 | where {$_ -ne ""} > c:\ziel.txt
 
$input = Get-Content C:\ziel.txt
$ip127 = $input

foreach($line in $ip127){
   
    if($line -notlike '*127.0.*'){
        echo $line >> $temp
    }
}
$path = "c:\ziel.txt"
Remove-Item $path
ren $temp $path
 
$input = Get-Content C:\ziel.txt
$akti = $input

foreach($line in $akti){
   
    if($line -notlike '*Aktive*'){
        echo $line >> $temp
    }
}
Remove-Item $path
ren $temp $path

$input = Get-Content C:\ziel.txt
$proto = $input

foreach($line in $proto){
   
    if($line -notlike '*Proto*'){
        echo $line >> $temp
    }
}
Remove-Item $path
ren $temp $path

$input = Get-Content C:\ziel.txt
$ster = $input

foreach($line in $ster){
   
    if (-not($line.Contains('*:*'))){
        echo $line >> $temp
    }
}
Remove-Item $path
ren $temp $path

$input = Get-Content C:\ziel.txt
$v6 = $input

foreach($line in $v6){
   
    if($line -notlike '*::*'){
        echo $line >> $temp
    }
}
Remove-Item $path
ren $temp $path

$input = Get-Content C:\ziel.txt
$inter = $input

foreach($line in $inter){
   
    if(-not($line.Contains('0.0.0.'))){
        echo $line >> $temp
    }
}
Remove-Item $path
ren $temp $path

$input = Get-Content C:\ziel.txt
foreach ($temp in $input)
{
    $String = $temp
    $zwischen = $String.Remove(0,32) | Out-file -FilePath $kurz -Append

}
 
  • Gefällt mir
Reaktionen: sikarr
Oh man, eine Filterfunktion ist in PS nun wirklich kinderleicht wenn man das Pipelining etwas verinnerlicht hat.
Hier mal exemplarisch:
PowerShell:
Get-Content $inputFile | ? {-not ($_.Trim() -eq "" -or $_ -like "0.0.0.*" -or $_ -like "127.*")} | Out-File $outputFile

Evtl. in eine function auslagern und noch um deine eigenen Bedingungen erweitern. das $_ in dem ScriptBlock entspricht 1 Textzeile aus Get-Content.

Ich würde nicht unter Originalnamen speichern, wenn dann eine Kopie in ein separates Verzeichnis.
 
Zeile 9 löscht alle Zeilen mit Leerzeichen
ab Zeile 14 löscht alle Zeilen mit 127.0.
ab Zeile 27 löscht alle Zeilen mit Aktive
ab Zeile 39 löscht alle Zeilen mit Proto
ab Zeile 51 löscht alle Zeilen mit Sternchen:Sternchen
ab Zeile 63 löscht alle Zeilen mit 2 Doppelpunkten
ab Zeile 75 löscht alle Zeilen mit 0.0.0.
Ergänzung ()

DaZpoon schrieb:
Oh man, eine Filterfunktion ist in PS nun wirklich kinderleicht wenn man das Pipelining etwas verinnerlicht hat.
Hier mal exemplarisch:
PowerShell:
Get-Content $inputFile | ? {-not ($_.Trim() -eq "" -or $_ -like "0.0.0.*" -or $_ -like "127.*")} | Out-File $outputFile
entfernt es nur die Zeichen oder jeweils die ganze zeile?
Wie ist es mit Sternchen im Suchtext? Deshalb habe ich es ja so aufgeteilt gemacht.
Ergänzung ()

DaZpoon schrieb:
Ich würde nicht unter Originalnamen speichern, wenn dann eine Kopie in ein separates Verzeichnis.
Den Originalnamen brauche ich weil es der Rechnername ist. Nur dann kann ich die Datei zuordnen
Ergänzung ()

Zur Verdeutlichung:
1683793983746.png


alle Zeilen mit den gelb markierten Suchbegriffen (ist nur ein Auszug der Datei) müssen gelöscht werden. Außerdem die Leerzeilen.

Das funktioniert mit dem Skript (nicht schön aber funktioniert) schon. Mein Problem ist wie ich alle .txt Dateien in einem Verzeichnis durcharbeiten lassen kann. Normalerweise muss ich beim Skript den Dateinamen mit übergeben. Wie bekomme ich den dann in das Skript?
Das Skript welches ich oben gepostet habe war mein Versuch dafür. Im Original fragt das Skript den Namen ab.

Die Probleme mit den Sternchen in den Suchbegriffen war nicht einfach. Sollte es einfacher gehen nutze ich es gerne. Bei like hatte ich das Problem das die Sternchen als Wildcard gewertet wurden und das Ergebnis dann eine leere Datei war. Deshalb auch die Nachfrage zu dem oben geposteten Vorschlag von DaZpoon.
 
Zuletzt bearbeitet:
Das Where-Object (mache ich immer kurz mit dem Operator ?) gibt nur alle Zeilen weiter an Out-File, welche die Bedingung erfüllen (daher das -not).
Statt dem Operator -like könntest du auch ein $_.Contains() verwenden (prüft kein Muster sondern ob der String einfach enthalten ist), denn die Sterne von ":" werden mit -like problematisch.
PowerShell:
param(
[Parameter(Mandatory=$true)]
[string]$LookupFolder,
[Parameter(Mandatory=$true)]
[string]$OutputFolder
)
if (-not (Test-Path $OutputFolder))
{
       New-Item $OutputFolder -ItemType Directory | Out-Null
}
# Iterate over all .txt files
foreach ($textFileInfo in (Get-ChildItem $LookupFolder -Filter "*.txt"))
{
    
    # Build the file name at the output folder
    $outFile = Join-Path $OutputFolder $textFileInfo.Name
    Get-Content $textFileInfo.FullName -Encoding Default  | ? {
        -not ( `
             $_.Trim() -eq "" `
         -or $_ -like "*0.0.0.*" `
         -or $_ -like "*127.0*" `
         -or $_.Contains("*:*")
        )
    } | Out-File $outFile -Encoding Default
}
Achtung, ungetestet.
Aufrufen kann man PowerShell dann direkt mit benannten Parametern

Code:
... FilterScript.ps1 -LookupFolder "D:\Temp" -OutputFolder "D:\Temp\Out"
 
Zuletzt bearbeitet:
Ich bekomme die Fehlermeldung bei dem Skript von dir:

Code:
In C:\local\dateien\bereinigen3.ps1:18 Zeichen:33
+                 $_.Trim() -eq ""     # Empty lines
+                                 ~
Schließende ")" fehlt in einem Ausdruck.
In C:\local\dateien\bereinigen3.ps1:16 Zeichen:63
+     Get-Content $textFileInfo.FullName -Encoding Default  | ? {
+                                                               ~
Die schließende "}" fehlt im Anweisungsblock oder der Typdefinition.
In C:\local\dateien\bereinigen3.ps1:12 Zeichen:74
+ ... ch ($textFileInfo in (Get-ChildItem $LookupFolder -Filter "*.txt")) {
+                                                                         ~
Die schließende "}" fehlt im Anweisungsblock oder der Typdefinition.
In C:\local\dateien\bereinigen3.ps1:24 Zeichen:13
+             )
+             ~
Unerwartetes Token ")" in Ausdruck oder Anweisung.
In C:\local\dateien\bereinigen3.ps1:25 Zeichen:9
+         } | Out-File $outFile -Encoding Default
+         ~
Unerwartetes Token "}" in Ausdruck oder Anweisung.
In C:\local\dateien\bereinigen3.ps1:25 Zeichen:11
+         } | Out-File $outFile -Encoding Default
+           ~
Ein leeres Pipeelement ist nicht zulässig.
In C:\local\dateien\bereinigen3.ps1:26 Zeichen:1
+ }
+ ~
Unerwartetes Token "}" in Ausdruck oder Anweisung.
    + CategoryInfo          : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : MissingEndParenthesisInExpression

allerdings kann ich keinen Fehler bei den Klammern finden
Ergänzung ()

Das Skript von dir verstehe ich dank der Erklärung. Leider gibt es Fehler zurück die nicht stimmen, die Klammern sind korrekt. Hast du eine Idee DaZpoon?
 
Zuletzt bearbeitet:
ok hier, dieses Script funktioniert aufjedenfall, du musst nur noch deine zu ersetzenden String noch einfügen, der rest funktioniert ;)

PowerShell:
# Ordnerpfad für die Eingabedateien
$inputFolder = "C:\Users\coldglow\Desktop\Ne"

# Ordnerpfad für den Ausgabeordner
$outputFolder = -join($inputFolder, "\Out")

# Array mit den zu ersetzenden Zeichenfolgen
$stringsToRemove = @("Aktive", "127.0.", "0.0.0.", "Proto")

# Erstelle den Ausgabeordner, falls er nicht existiert
if (-not (Test-Path -Path $outputFolder)) {
    New-Item -ItemType Directory -Path $outputFolder | Out-Null
}

# Durchlaufe den Eingabeordner
Get-ChildItem -Path $inputFolder -Filter "*.txt" | ForEach-Object {
    # Lese den Inhalt der aktuellen Datei
    $content = Get-Content $_.FullName

    # Durchlaufe das Array mit den zu ersetzenden Zeichenfolgen
    foreach ($string in $stringsToRemove) {
        $content = $content -creplace [regex]::Escape($string), ""
    }

    $content = $content -replace "\s{2,}", " "
   
    $content = $content | Where-Object { $_ -match '\S' } | ForEach-Object { $_.Trim() }


    # Dateiname für die Ausgabedatei
    $outputFileName = Join-Path -Path $outputFolder -ChildPath $_.Name

    # Speichere den bereinigten Inhalt in die Ausgabedatei
    $content | Set-Content -Path $outputFileName
}
Ergänzung ()

so push.. sorry, nochmal geändert, sah garnicht schön aus... hab das noch schnell noch das mit den arrays eingefügt
 
Zuletzt bearbeitet: (noch auf arrays umgestellt...)
  • Gefällt mir
Reaktionen: s1ave77
Sorry, hatte vergessen dass PS da ein wenig knarzig ist mit den mehrzeiligen Commands. Ich habe es korrigiert. Es fehlten diese tollen "Backticks" ` (Umschalt + Akzent)
 
Zurück
Oben