Wie kann ich in Win7 in jeder Zeile ein Dokument nach einem Teilstring sortieren?

1483
Joey Hammer

Wie kann ich einen Text nach Hashtag unter Windows-7 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 folgendermaßen aussieht:

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

Ich muss das täglich tun, also möchte ich es in möglichst wenigen Schritten tun können.

0
Neben dem Vorschlag, welche Software verwendet werden soll, definieren Sie bitte auch die genaue Vorgehensweise. Joey Hammer vor 12 Jahren 1
Schritt 1: Ersetzen Sie `#` durch `, #`. Schritt 2: Importieren Sie als CSV in Excel oder eine ähnliche Anwendung. Der Hochstapler vor 12 Jahren 2
In Ihrem Kommentar heißt es an anderer Stelle: "Das Skript oder whatnot muss nicht klug genug sein, um mit langen Zeilen mit Zeilenumbrüchen zu arbeiten", dass kein zuverlässiger Begrenzer ist? ist der Datensatzbegrenzer ein `# [sometext] `? horatio vor 12 Jahren 1
Aktualisieren Sie Ihre Frage mit allen zusätzlichen Informationen zum Format der Eingabedateien. martineau vor 12 Jahren 0
@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 vor 12 Jahren 0
@martineau: Es tut mir leid, es war nicht wirklich eine Lösung, obwohl es für mich funktionierte. Ich möchte nicht jemandem empfehlen müssen, ein Biest wie Excel zu verwenden, um eine solche Aufgabe zu lösen. Ihr habt schon viel bessere Beispiele gefunden :) Der Hochstapler vor 12 Jahren 0

3 Antworten auf die Frage

1
Sean C.

Hier ist eine letzte Powershell-Lösung, die sich mit neuen Linien befassen wird. Als Trennzeichen wird ein Hashtag gefolgt von Wortzeichen gefolgt von angenommen. Bei einer Datenzeile ohne Hash-Tag wird davon ausgegangen, dass die Daten bis zur nächsten Zeile fortgesetzt werden. Die anderen Informationen unterhalb dieses Abschnitts meiner Antwort beziehen sich nicht auf den vom Autor genannten Sonderfall, bei dem Daten eine neue 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 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 startet im Befehlsmodus. 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 den Hashtag am Zeilenende an den Zeilenanfang. Der zweite Befehl sortiert die Daten und der dritte Befehl macht den Swap rückgängig und verschiebt den Hashtag an das Ende der Zeile.

Ich habe dies an Ihrem Beispiel getestet und es funktioniert.


@Oliver_Salzburg lieferte eine viel einfachere Antwort in Excel. Ich dachte nicht über den Tellerrand und gab eine Antwort mit einem Texteditor.

Schritt 1: Ersetzen #mit ,#Schritt 2: Importieren Sie als CSV in Excel oder eine ähnliche Anwendung. - Oliver Salzburg ♦


Hier ist eine Lösung, bei der nur Powershell verwendet wird, die nativ unter Win7 ausgeführt werden kann. Ich hatte immer noch keine Gelegenheit, sich über das Durchqueren von Zeilenumbrüchen zu informieren, daher berücksichtigt diese Lösung diese nicht.

In diesem Beispiel wird davon ausgegangen, dass die Datei, mit der Sie arbeiten, ist test.txt.

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

Eine Zwischenlage mit Hebelschalen.

((get-content test.txt) -replace '^(.*)\ (#\w+)$', '$2 $1' | Sort-Object) -replace '^(#\w+)\ (.*)$','$2 $1' | out-file test.txt -encoding ascii 
(OS: Win7). Die Excel-Lösung war mir bereits bekannt. Da ich dies jedoch ziemlich oft mache (bis zu zehn Mal am Tag), ist es unbequem, die Datei weiterhin in CSV zu konvertieren, Excel zu öffnen, auf die Sortierschaltflächen zu klicken usw. Möglicherweise gibt es eine Möglichkeit, eine Batchdatei zu erstellen ... Idealerweise Ich möchte nur einmal klicken, ein Skript oder etwas aktivieren, das sich um alles kümmert und in eine neue Datei ausgibt. Joey Hammer vor 12 Jahren 0
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 vor 12 Jahren 0
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 mit der Lösung komme, sie entzieht sich meiner Erinnerung. Sean C. vor 12 Jahren 0
Ein weiterer Punkt: Wenn Sie sich für Vim interessieren, können Sie benutzerdefinierte Funktionen und Makros erstellen. Auf diese Weise können Sie beispielsweise einen Befehl wie:: sorthash eingeben und die Befehle in der richtigen Reihenfolge ausführen. Sean C. vor 12 Jahren 0
Ich verwende Dreamweaver normalerweise. Ich habe auch eine Kopie von Vim, aber ich verwende sie nicht so oft. Wenn dieses Problem in Vim gelöst werden kann, wäre das nett. Noch schöner wäre es, wenn ich ein Skript automatisch ausführen könnte, um Vim nicht wirklich öffnen und die Datei jedes Mal laden zu müssen. Wenn Sie beispielsweise auf ein Desktopsymbol doppelklicken, um ein Skript auszuführen, wird das Dokument sortiert und unter einem neuen Namen in einem Ordner Ihrer Wahl gespeichert. Joey Hammer vor 12 Jahren 0
Wenn Sie unxutils für Windows installieren, könnte dies problemlos mit einem Skript erfolgen. `sed` und` sort` könnten das schaffen. Ich bin im Moment in der Arbeit und ich wurde weggerufen. Ich werde die Antwort mit einigen Skriptlösungen aktualisieren, wenn ich meine Arbeit beendet habe. Sean C. vor 12 Jahren 0
OK. Ich habe jetzt zwei Ordner auf dem Desktop, bin und usr. Danke fürs Helfen. Bitte lassen Sie mich wissen, wenn Sie die Lösung haben:) Joey Hammer vor 12 Jahren 0
Eh Rajesh, er hat noch nicht die volle Lösung bereitgestellt. Joey Hammer vor 12 Jahren 0
Ich habe. \ Test.txt in c: \ blah \ blah \ test.txt geändert. Das scheint in Ordnung zu sein, aber ich bekomme eine Fehlermeldung für den letzten Teil des Skripts: PS C: \ Users \ Pongy> ($ fixedFile -replace) '^ (. *) \ (#. *) $', '$ 2 $ 1' | Sortierobjekt) -replace '^ (# \ w +) \ (. *) $', '$ 2 $ 1' | outf ile test.txt -encoding ascii Der Begriff "outfile" wird nicht als Name eines Cmdlets, einer Funktion, einer Skriptdatei oder eines bedienbaren Programms erkannt. Überprüfen Sie den Namen des Namens oder prüfen Sie, ob der Pfad korrekt ist, und versuchen Sie es erneut. Joey Hammer vor 12 Jahren 0
In Zeile: 1 Zeichen: 105 + ($ fixedFile -replace '^ (. *) \ (#. *) $', '$ 2 $ 1' | Sort-Object) -replace '^ (# \ w +) \ (. *) ) $ ',' $ 2 $ 1 '| outfile <<<< test.t xt -encoding ascii + CategoryInfo: ObjectNotFound: (outfile: String) [], CommandNotFoundException + FullyQualifiedErrorId: CommandNotFoundException Joey Hammer vor 12 Jahren 0
@JoeyHammer Ich habe einen Fehler gemacht, den ich korrigiert habe. "outfile" sollte "out-file" sein. Sean C. vor 12 Jahren 0
1
martineau

Here's a Windows batch (.bat) or command (.cmd) file that will do it. I wasn't sure what you wanted to do with the output, so this just displays one of the two temporary files it creates and then deletes both of them.

@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 
Dies ist eine schöne Lösung, behandelt jedoch keine Zeilenumbrüche, wie in den Kommentaren der Antwort, die ich gegeben habe (zweiter Kommentar). Sean C. vor 12 Jahren 0
@Sean C .: Aus dem Kommentar war nicht ersichtlich, dass es einen Zeilenumbruch in der Zeile gab. Am besten wäre es, wenn das OP seine Frage aktualisiert und den möglichen Inhalt der Eingabedatei besser beschreibt. Ich frage mich, ob das einfache Erkennen, dass eine Zeile kein "#" hatte, ausreichen würde, um anzunehmen, dass sie auf der nächsten (oder mehr) fortgesetzt wurde. martineau vor 12 Jahren 0
Die endgültige Powershell-Lösung sucht nach dem Vorhandensein eines Hash-Tags am Ende der Zeile `/ # \ w + $ /`. Falls dieser nicht vorhanden ist, wird davon ausgegangen, dass die Daten in der nächsten Zeile fortgesetzt werden. Sean C. vor 12 Jahren 0
@SeanC .: Die Antwort / Anmerkung von Oliver_Salzburg zum Importieren in Excel würde wahrscheinlich auch nicht mit unterbrochenen Linien umgehen (ohne benutzerdefinierte VBA-Codierung). Allerdings geht mir, genau wie Sie, diese inhaltliche Frage nicht aus. martineau vor 12 Jahren 0
0
Der Hochstapler

Wenn Sie unter Windows arbeiten, 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 optimale 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 # )} 
@Oliver_Salzburg Diese Lösung behandelt nicht den Fall, in dem Daten mehrere Zeilenumbrüche umfassen. Siehe Kommentar # 2 in meiner Antwort. Sean C. vor 12 Jahren 0
@Oliver_Salzburg Können Sie auch erklären, warum Sie sich für die .NET-Klasse io.file entschieden haben? Warum nicht einfach "get-content" verwenden? Ihr Einzeiler könnte leicht `get-content test.txt | gewesen sein Sortierobjekt {$ _. SubString ($ _. IndexOf ('#'))} ` Sean C. vor 12 Jahren 0
@SeanC .: Meine Antwort bezieht sich auf das in der Frage gestellte Problem. Der Hochstapler vor 12 Jahren 0
@SeanC .: Weil ich mit .NET-Klassen besser vertraut bin als mit Cmdlets. Der Hochstapler vor 12 Jahren 0