wake-up-neo.com

Extrahieren Sie Zeilen, die einem Muster entsprechen, aus allen Textdateien in einem Ordner in eine einzelne Ausgabedatei

Ich versuche, jede Zeile, die mit "%%" beginnt, in allen Dateien in einem Ordner zu extrahieren und diese Zeilen dann in eine separate Textdatei zu kopieren. Derzeit wird dieser Code in PowerShell-Code verwendet, es werden jedoch keine Ergebnisse angezeigt. 

$files = Get-ChildItem "folder" -Filter *.txt
foreach ($file in $files)
{
if ($_ -like "*%%*")
{
Set-Content "Output.txt" 
}  
}
6
Jabir Jamal

Ich denke, dass der Vorschlag von mklement0, Select-String zu verwenden, der richtige Weg ist. Zusätzlich zu seiner Antwort können Sie die Ausgabe von Get-ChildItem in Select-String leiten, sodass der gesamte Prozess zu einem Powershell-One-Liner wird. 

Etwas wie das:

Get-ChildItem "folder" -Filter *.txt | Select-String -Pattern '^%%' | Select -ExpandProperty line | Set-Content "Output.txt"
12
Dave Sexton

Das Cmdlet Select-String Bietet eine viel einfachere Lösung (PSv3 + -Syntax):

(Select-String -Path folder\*.txt -Pattern '^%%').Line | Set-Content Output.txt
  • Select-String Akzeptiert ein Dateinamen-/Pfadmuster über den Parameter -Path. In diesem einfachen Fall ist Get-ChildItem Nicht erforderlich.

    • Wenn Ihre Eingabedateiauswahl dagegen rekursiv ist oder komplexere Kriterien verwendet, können Sie die Ausgabe von Get-ChildItem An Select-String Weiterleiten, wie in Dave Sextons hilfreiche Antwort gezeigt =.
    • Beachten Sie, dass laut Dokumentation , Select-String Standardmäßig davon ausgeht, dass die Eingabedateien UTF-8-codiert sind. Sie können dies jedoch mit dem Parameter -Encoding Ändern. Beachten Sie auch die unten beschriebene Ausgabe Kodierung.
  • Der Parameter Select-String Von -Pattern Erwartet ein regulärer Ausdruck anstelle eines Platzhalterausdrucks.
    ^%% Entspricht nur dem Literal %% Am Start ​​(^) Einer Zeile.

  • Select-String Gibt [Microsoft.PowerShell.Commands.MatchInfo]objects aus, die Informationen zu jeder Übereinstimmung enthalten; Die Eigenschaft .Line jedes Objekts enthält den vollständigen Text einer übereinstimmenden Eingabezeile.

  • Set-Content Output.txt Sendet alle übereinstimmenden Zeilen an eine einzige Ausgabedatei Output.txt

    • Set-Content Verwendet die alte Windows-Codepage des Systems (eine 8-Bit-Einzelbyte-Codierung - obwohl die Dokumentation fälschlicherweise behauptet, dass ~ # ~] ascii [~ # ~ ] Dateien werden erzeugt).
      Wenn Sie die Ausgabecodierung explizit steuern möchten, verwenden Sie den Parameter -Encoding. z. B. ... | Set-Content Output.txt -Encoding Utf8.
    • Im Gegensatz dazu erstellt der Ausgabeumleitungsoperator >immer UTF-16LE-Dateien (eine PowerShell-Codierung ruft Unicode auf), ebenso wie Out-File - standardmäßig (kann mit -Encoding geändert werden).
      Beachten Sie auch, dass >/Out-File Die Standardformatierung von PowerShell auf die Eingabeobjekte anwendet, um die Zeichenfolgendarstellung zum Schreiben in die Ausgabedatei zu erhalten, wohingegen Set-Content Das behandelt Eingabe als Strings (ruft bei Bedarf .ToString() für Eingabeobjekte auf). Im vorliegenden Fall gibt es keinen Unterschied, da alle Eingabeobjekte bereits Zeichenfolgen sind (möglicherweise mit Ausnahme der Zeichencodierung).

Wie für , was Sie versucht haben :

  • $_ In Ihrer foreach ($file in $files) verweist auf ein file (ein [System.IO.FileInfo] - Objekt), sodass Sie Ihren Platzhalterausdruck *%%* gegen die Name der Eingabedatei und nicht gegen deren Inhalt.

  • Abgesehen davon stimmt das Platzhaltermuster *%%* Mit %%Irgendwo in der Eingabezeichenfolge überein, nicht nur mit Start ​​(Sie müssten stattdessen %%* verwenden).

  • Der Aufruf Set-Content "Output.txt" Fehlt input, da er nicht Teil einer Pipeline ist und bei fehlender Pipelineeingabe kein Argument -Value Übergeben wurde.

    • Selbst wenn Sie eine Eingabe gemacht hätten, würde die Ausgabedatei Output.txtals Ganzes umgeschrieben in jeder Iteration Ihrer foreach -Schleife erhalten.
7
mklement0
ls *.txt | %{
$f = $_
  gc $f.fullname | {
     if($_.StartWith("%%") -eq 1){
        $_ >> Output.txt
     }#end if
  }#end gc
}#end ls

Alias

ls - Get-ChildItem
gc - Get-Content
% - ForEach
$_ - Iterator variable for loop
>> - Redirection construct
# - Comment

http://ss64.com/ps/

1
Shantanu Gupta

Zuerst musst du verwenden 

Get-Content

um den Inhalt der Datei zu erhalten. Dann passen Sie die Zeichenfolge an und auf dieser Grundlage werden Sie wieder setzen Sie den Inhalt zurück zur Datei. Verwenden Sie get-content und fügen Sie eine weitere Schleife in foreach ein, um alle Zeilen in der Datei zu durchlaufen.

Ich hoffe diese Logik hilft dir

0
Ranadip Dutta