Wie kann ich die Zeilen in einer Datei mit Standardtools unter Red Hat Linux zufällig sortieren?
Ich habe den shuf
Befehl nicht, also suche ich nach etwas wie einem perl
oder awk
einem 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 shuf
Befehl nicht, also suche ich nach etwas wie einem perl
oder awk
einem 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 -i
Flag ("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)
shuf
alles 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 coreutils
Allen Utils wird ag so vorangestellt: gsort --random-sort
oder gshuf
sie funktionieren wie erwartet
gsort
und gshuf
installierte es auch, als ich es tatport install coreutils
shuf
stattdessen (unter Linux).
shuf
ist der beste Weg.
sort -R
ist schmerzhaft langsam. Ich habe gerade versucht, 5 GB Datei zu sortieren. Ich gab nach 2,5 Stunden auf. Dann shuf
sortierte es in einer Minute.
sort -R
dafü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. "
shuf
lädt alles in den Speicher.
seq -f 'line %.0f' 1000000
dauerte 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 f
durch while IFS= read -r f
wird verhindert, read
dass 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 cut
fü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 ~/.bashrc
enthä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,c
ist eine Abkürzung für-e 'use module qw(a b c);'
.)
Der Grund dafür, dass das einfache -i
Mischen nicht funktioniert, ist, dass Perl erwartet, dass print
dies 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. ( -n
bedeutet "den Code in eine while (<>) {...}
Schleife einschließen; BEGIN{undef$/}
lässt Perl Dateien einzeln anstatt zeilenweise bearbeiten und split/^/m
wird 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