Wie kann ich die Zeilen in einer Datei mit Standardtools unter Red Hat Linux zufällig sortieren?
Ich habe den shufBefehl nicht, also suche ich nach etwas wie einem perloder awkeinem Einzeiler, der die gleiche Aufgabe erfüllt.
Wie kann ich die Zeilen in einer Datei mit Standardtools unter Red Hat Linux zufällig sortieren?
Ich habe den shufBefehl nicht, also suche ich nach etwas wie einem perloder awkeinem Einzeiler, der die gleiche Aufgabe erfüllt.
Antworten:
Und einen Perl-Einzeiler bekommen Sie!
perl -MList::Util -e 'print List::Util::shuffle <>'
Es wird ein Modul verwendet, das Modul ist jedoch Teil der Perl-Codeverteilung. Wenn das nicht gut genug ist, können Sie erwägen, Ihre eigenen zu rollen.
Ich habe versucht, dies mit dem -iFlag ("Edit-in-Place") zu verwenden, damit die Datei bearbeitet wird. Die Dokumentation schlägt vor, dass es funktionieren sollte, aber es funktioniert nicht. Die gemischte Datei wird weiterhin in stdout angezeigt, diesmal wird jedoch das Original gelöscht. Ich schlage vor, Sie verwenden es nicht.
Betrachten Sie ein Shell-Skript:
#!/bin/sh
if [[ $# -eq 0 ]]
then
echo "Usage: $0 [file ...]"
exit 1
fi
for i in "$@"
do
perl -MList::Util -e 'print List::Util::shuffle <>' $i > $i.new
if [[ `wc -c $i` -eq `wc -c $i.new` ]]
then
mv $i.new $i
else
echo "Error for file $i!"
fi
done
Ungetestet, funktioniert aber hoffentlich.
ruby -e 'puts STDIN.readlines.shuffle'. Es müsste an großen Eingängen getestet werden, um festzustellen, ob die Geschwindigkeit vergleichbar ist. (funktioniert auch unter OS X)
shufalles in den Speicher geladen, sodass es mit einer wirklich großen Datei nicht funktioniert (meine ist ~ 300 GB tsv). Dieses Perl-Skript ist auch bei mir fehlgeschlagen, aber ohne Fehler außer Killed. Irgendeine Idee, ob die Perl-Lösung auch alles in den Speicher lädt, oder gibt es ein anderes Problem, auf das ich stoße?
Ähm, vergessen wir nicht
sort --random-sort
brew install coreutilsAllen Utils wird ag so vorangestellt: gsort --random-sortoder gshufsie funktionieren wie erwartet
gsortund gshufinstallierte es auch, als ich es tatport install coreutils
shufstattdessen (unter Linux).
shuf ist der beste Weg.
sort -Rist schmerzhaft langsam. Ich habe gerade versucht, 5 GB Datei zu sortieren. Ich gab nach 2,5 Stunden auf. Dann shufsortierte es in einer Minute.
sort -Rdafür ist, dass für jede Zeile ein Hash berechnet wird. Aus den Dokumenten: " Sortieren durch Hashing der Eingabetasten und anschließendes Sortieren der Hashwerte. "
shuflädt alles in den Speicher.
seq -f 'line %.0f' 1000000dauerte das Sortieren einer Eingabedatei mit 1 Million Zeilen, die mit erstellt wurde, dieselbe lange Zeit (viel, viel länger als mit shuf), unabhängig davon, wie viel Speicher ich zugewiesen habe.
cat yourfile.txt | while IFS= read -r f; do printf "%05d %s\n" "$RANDOM" "$f"; done | sort -n | cut -c7-
Lesen Sie die Datei, stellen Sie jeder Zeile eine Zufallszahl voran, sortieren Sie die Datei nach diesen zufälligen Präfixen und schneiden Sie die Präfixe anschließend aus. Einzeiler, der in jeder halbmodernen Schale funktionieren sollte.
EDIT: Richard Hansens Bemerkungen aufgenommen.
$RANDOM), aber -1 für das Abschlachten der Daten. Durch Ersetzen while read fdurch while IFS= read -r fwird verhindert, readdass führende und nachfolgende Leerzeichen entfernt werden (siehe diese Antwort ) und die Verarbeitung von Backslashes verhindert wird. Durch die Verwendung einer zufälligen Zeichenfolge mit fester Länge wird verhindert, dass cutführende Leerzeichen gelöscht werden. Ergebnis: cat yourfile.txt | while IFS= read -r f; do printf "%05d %s\n" "$RANDOM" "$f"; done | sort -n | cut -c7-
Ein Einzeiler für Python:
python -c "import random, sys; lines = open(sys.argv[1]).readlines(); random.shuffle(lines); print ''.join(lines)," myFile
Und zum Drucken nur einer einzigen zufälligen Zeile:
python -c "import random, sys; print random.choice(open(sys.argv[1]).readlines())," myFile
Aber siehe diesen Beitrag für die Nachteile von Python random.shuffle(). Es funktioniert nicht gut mit vielen (mehr als 2080) Elementen.
Bezogen auf Jims Antwort:
Mein ~/.bashrcenthält Folgendes:
unsort ()
{
LC_ALL=C sort -R "$@"
}
Mit GNU coreutils 'sort, -R= --random-sort, das einen zufälligen Hash jeder Zeile generiert und danach sortiert. Der randomisierte Hash würde in einigen Gebietsschemas in einigen älteren (fehlerhaften) Versionen nicht verwendet, was dazu führt, dass er eine normal sortierte Ausgabe zurückgibt, weshalb ich ihn festgelegt habe LC_ALL=C.
Bezogen auf Chris 'Antwort:
perl -MList::Util=shuffle -e'print shuffle<>'
ist ein etwas kürzerer Einzeiler. ( -Mmodule=a,b,cist eine Abkürzung für-e 'use module qw(a b c);' .)
Der Grund dafür, dass das einfache -iMischen nicht funktioniert, ist, dass Perl erwartet, dass printdies in derselben Schleife geschieht, in der die Datei gelesen wird, undprint shuffle <> erst ausgegeben wird, nachdem alle Eingabedateien gelesen und geschlossen wurden.
Als kürzere Problemumgehung
perl -MList::Util=shuffle -i -ne'BEGIN{undef$/}print shuffle split/^/m'
mischt Dateien an Ort und Stelle. ( -nbedeutet "den Code in eine while (<>) {...}Schleife einschließen; BEGIN{undef$/}lässt Perl Dateien einzeln anstatt zeilenweise bearbeiten und split/^/mwird benötigt, weil $_=<>implizit mit einer gesamten Datei anstelle von Zeilen gearbeitet wurde.)
FreeBSD hat ein eigenes zufälliges Dienstprogramm:
cat $file | random | ...
Es befindet sich in / usr / games / random. Wenn Sie also keine Spiele installiert haben, haben Sie kein Glück.
Sie können Ports wie textproc / rand oder textproc / msort installieren. Diese sind möglicherweise unter Linux und / oder Mac OS X verfügbar, wenn die Portabilität ein Problem darstellt.
Unter OSX das Neueste von http://ftp.gnu.org/gnu/coreutils/ und so ähnlich
./configure make sudo make install
... sollte Ihnen / usr / local / bin / sort --random-sort geben
ohne / usr / bin / sort durcheinander zu bringen
Oder erhalten Sie es von MacPorts:
$ sudo port install coreutils
und / oder
$ /opt/local//libexec/gnubin/sort --random-sort