Wie kann ich unter Win7 ein Dokument nach einer Teilzeichenfolge in jeder Zeile sortieren?

0

Wie kann ich unter Windows-7 einen Text nach Hashtag sortieren?

Ich habe einen langen Text (TXT-Format), der ungefähr so ​​aussieht:

  • Blah blah #Test
  • 123123 #Wirklich
  • Blah bluh #Wirklich
  • klfdmngl #Test

Ich möchte den Text bequem, schnell und automatisch so sortieren können, dass er so aussieht:

  • Blah blah #Test
  • klfdmngl #Test
  • 123123 #Wirklich
  • Blah bluh #Wirklich

Ich muss das täglich machen, damit ich es in so wenigen Schritten wie möglich machen kann.

Joey Hammer
quelle
1
Abgesehen davon, dass Sie nur die zu verwendende Software vorschlagen, definieren Sie bitte auch die genaue Vorgehensweise.
Joey Hammer
2
Schritt 1: Ersetzen #durch ,#Schritt 2: Als CSV in Excel oder eine ähnliche Anwendung importieren.
Der Hochstapler
1
Ihr Kommentar an anderer Stelle besagt, dass {EOL} kein zuverlässiger Begrenzer ist. ist das Datensatztrennzeichen ein #[sometext]{eol}?
Horatio
Bitte aktualisieren Sie Ihre Frage mit allen zusätzlichen Informationen zum Eingabedateiformat.
Martineau
@Oliver Salzburg: Ich denke, das OP möchte auch wissen, was zu tun ist, nachdem es in Excel importiert wurde oder was auch immer?
Martineau

Antworten:

1

Hier ist eine Windows-Batchdatei (.bat) oder eine Befehlsdatei (.cmd), die dies erledigt. Ich war mir nicht sicher, was Sie mit der Ausgabe machen wollten, daher zeigt diese nur eine der beiden temporären Dateien an, die sie erstellt und dann beide löscht.

@echo off
if {%1} == {} (
echo usage: %0 ^<filename^>
goto :EOF
)
echo.>_temp1
for /F "tokens=1,2 delims=#" %%i in (%1) do echo %%j$%%i>>_temp1
echo.>_temp2
sort _temp1 >_temp2
echo.>_temp1
for /F "tokens=1,2 delims=$" %%i in (_temp2) do @echo %%j#%%i>>_temp1
type _temp1
del _temp1
del _temp2
Martineau
quelle
Dies ist eine nette Lösung, aber sie behandelt keine Zeilenumbrüche, wie in den Kommentaren der Antwort erwähnt (zweiter Kommentar).
Sean C.
@ Sean C .: Aus den Kommentaren war nicht ersichtlich, dass die Zeile einen Zeilenumbruch enthielt. Es ist am besten, wenn das OP seine Frage aktualisiert und den möglichen Inhalt der Eingabedatei besser beschreibt. Ich frage mich, ob das bloße Erkennen, dass eine Zeile nicht vorhanden ist #, ausreichen würde, um anzunehmen, dass sie bei der nächsten (oder mehreren) fortgesetzt wurde.
Martineau
Bei der endgültigen Powershell-Lösung wird das Vorhandensein eines Hash-Tags am Ende der Zeile überprüft. /#\w+$/Wenn es nicht vorhanden ist, wird davon ausgegangen , dass die Daten in der nächsten Zeile fortgesetzt werden.
Sean C.
@SeanC .: Oliver_Salzburgs Antwort / Kommentar zum Importieren in Excel würde wahrscheinlich auch keine unterbrochenen Linien verarbeiten (ohne eine benutzerdefinierte VBA-Codierung). Wie Sie geht mir jedoch in Bezug auf diese nicht näher spezifizierte Frage die Puste aus.
Martineau
1

Hier ist eine letzte PowerShell-Lösung, die sich mit neuen Linien befasst. Als Trennzeichen wird ein Hashtag gefolgt von Wortzeichen gefolgt von {EOL} angenommen. Bei einer Datenzeile ohne Hash-Tag wird davon ausgegangen, dass die Daten in der nächsten Zeile fortgesetzt werden. Die anderen Informationen unter diesem Abschnitt meiner Antwort befassen sich nicht mit dem vom Autor erwähnten Sonderfall, bei dem Daten eine Newline-Grenze überschreiten. In diesem Beispiel wird davon ausgegangen, dass die Datei test.txt heißt und sich im aktuellen Verzeichnis befindet.

[string[]]$fileContent = (get-content .\test.txt);
[string]$linebuffer = '';

[object]$fixedFile = foreach($line in $fileContent) {
    if(-not ($line -match "#\w+$")) {
        $linebuffer += ($line + ' ');
        continue;
    }

    $linebuffer += $line;
    $linebuffer;
    $linebuffer = '';
}

($fixedFile -replace '^(.*)\ (#.*)$', '$2 $1' | Sort-Object) -replace '^(#\w+)\ (.*)$','$2 $1' | out-file test.txt -encoding ascii

Verwenden Sie gVim unter Windows oder MacVim unter OS X.

HINWEIS: Vim ist ein Editor mit 2 Modi. Einfüge- / Bearbeitungsmodus und Befehlsmodus. Um Text tatsächlich wie einen normalen Editor zu bearbeiten, müssen Sie sich im Bearbeitungsmodus befinden, der das Drücken einer Taste wie aoder erfordert i. Der Editor wird im Befehlsmodus gestartet. Im Befehlsmodus können Sie einfach einen Doppelpunkt eingeben, um diese Befehle einzugeben.

:%s/^\(.*\)\ \(\#\w\+\)$/\2\ \1/g
:sort
:%s/^\(\#\w\+\)\ \(.*\)$/\2\ \1/g

Der erste Befehl tauscht das Hashtag am Zeilenende gegen den Zeilenanfang aus. Der zweite Befehl sortiert die Daten und der dritte Befehl macht den Tausch rückgängig und verschiebt das Hashtag zurück an das Ende der Zeile.

Ich habe dies an Ihrer Probe getestet und es funktioniert.


@Oliver_Salzburg gab mit Excel in Kommentaren eine viel einfachere Antwort. Ich habe nicht über den Tellerrand hinaus gedacht und mit einem Texteditor geantwortet.

Schritt 1: Ersetzen #durch ,#Schritt 2: Als CSV in Excel oder eine ähnliche Anwendung importieren. - Oliver Salzburg ♦


Hier ist eine Lösung, die nur Powershell verwendet und von Haus aus unter Win7 ausgeführt werden kann. Ich hatte immer noch keine Gelegenheit, über durchlaufende Zeilenumbrüche nachzulesen, daher berücksichtigt diese Lösung diese nicht.

In diesem Beispiel wird davon ausgegangen, dass es sich bei der Datei, mit der Sie arbeiten, um handelt test.txt.

$tempstor = (get-content test.txt) -replace '^(.*)\ (#.*)$', '$2 $1' | Sort-Object
$tempstor -replace '^(#\w+)\ (.*)$','$2 $1' | out-file test.txt -encoding ASCII

Ein Liner, Hebel Unterschalen.

((get-content test.txt) -replace '^(.*)\ (#\w+)$', '$2 $1' | Sort-Object) -replace '^(#\w+)\ (.*)$','$2 $1' | out-file test.txt -encoding ascii
Sean C.
quelle
(Betriebssystem: Win7). Die Excel-Lösung war mir bereits bekannt. Da ich dies jedoch ziemlich oft mache (bis zu zehn Mal am Tag), ist es unpraktisch, die Datei weiterhin in CSV zu konvertieren, Excel zu öffnen, auf die Sortierschaltflächen zu klicken usw. Vielleicht gibt es eine Möglichkeit, eine Batch-Datei zu erstellen ... Idealerweise Ich möchte nur einmal klicken, ein Skript aktivieren oder etwas, das sich um alles kümmert und in eine neue Datei ausgibt.
Joey Hammer
Eine weitere Sache: einige Zeilen lang sind und aussehen wie folgt aus : blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah #Hashtag - so das Skript oder Dingsbums hat sein klug genug , mit langen Linien mit Zeilenumbrüche zu arbeiten.
Joey Hammer
Dies ist auch mit vim möglich, erfordert jedoch einen zusätzlichen Schalter am Ende des Befehls, um Zeilenumbrüche zu durchlaufen. Ich werde die ursprüngliche Antwort aktualisieren, wenn ich eine Lösung finde, die sich meinem Gedächtnis entzieht.
Sean C.
Ein weiterer Punkt, wenn Sie Vim lernen möchten, können Sie benutzerdefinierte Funktionen und Makros erstellen. Auf diese Weise können Sie :sorthashbeispielsweise einen Befehl eingeben und die Befehle in der richtigen Reihenfolge ausführen.
Sean C.
Ich benutze Dreamweaver normalerweise. Ich habe auch eine Kopie von Vim, aber ich benutze sie (überhaupt) nicht so oft. Wenn dieses Problem in Vim gelöst werden kann, wäre das schön. Noch schöner wäre es, wenn ich ein Skript automatisch ausführen könnte, damit ich Vim nicht jedes Mal öffnen und die Datei laden müsste. Doppelklicken Sie einfach auf ein Desktop-Symbol, das ein Skript ausführt, sortiert das Dokument und speichert es unter einem neuen Namen in einem Ordner Ihrer Wahl.
Joey Hammer
0

Unter Windows können Sie dieses einfache PowerShell-Skript verwenden:

[io.file]::ReadAllLines("test.txt")|Sort-Object {$_.SubString($_.IndexOf('#'))}

Ich bin kaum ein PowerShell-Experte. Tut mir leid, wenn es eine optimalere Lösung gibt :)

Beispiel

Hier ist der Inhalt meiner Eingabedatei test.txt:

PS C:\Users\Oliver> type test.txt
Blah blah #Test
123123 #Really
Oliver #SuperUser
Blah bluh #Really
klfdmngl #Test

Dies ist die Ausgabe, wenn das obige Skript ausgeführt wird:

PS C:\Users\Oliver> [io.file]::ReadAllLines("test.txt")|Sort-Object {$_.SubString($_.IndexOf('#'))}
Blah bluh #Really
123123 #Really
Oliver #SuperUser
klfdmngl #Test
Blah blah #Test

Analyse

[io.file]       # From the module io.file...
::ReadAllLines  # use method ReadAllLines to read all text lines into an array...
("test.txt")    # from the file test.txt

|               # Take that array and pipe it to...
Sort-Object     # the cmdlet Sort-Object (to sort objects)
{               # To sort the elements in the array...
$_.SubString(   # use the part of the text line...
$_.IndexOf('#') # that starts at the first position of a #
)}
Der Hochstapler
quelle
@Oliver_Salzburg Diese Lösung behandelt nicht den Fall, dass Daten mehrere Zeilenumbrüche umfassen. Siehe Kommentar Nr. 2 in der Antwort, die ich gegeben habe.
Sean C.
@Oliver_Salzburg Können Sie auch erklären, warum Sie sich für die .NET io.file-Klasse entschieden haben? Warum nicht einfach benutzen get-content? Ihr get-content test.txt | sort-object {$_.SubString($_.IndexOf('#'))}
Sean C.
@ SeanC .: Meine Antwort bezieht sich auf das in der Frage aufgeworfene Problem.
Der Hochstapler
@ SeanC .: Weil ich mit .NET-Klassen besser vertraut bin als mit Cmdlets.
Der Hochstapler