Wie kann ich eine Textdatei mit dem Befehl split in 70% und 30% aufteilen?
Wie kann ich eine Textdatei mit dem Befehl split in 70% und 30% aufteilen?
Antworten:
Die folgenden Befehle funktionieren für Prozentsätze über 50% (wenn Sie nur in zwei Dateien aufteilen möchten), schnelles und unsauberes Vorgehen.
1) 70% basierend auf Linien aufgeteilt
split -l $[ $(wc -l filename|cut -d" " -f1) * 70 / 100 ] filename
2) 70% basierend auf Bytes teilen
split -b $[ $(wc -c filename|cut -d" " -f1) * 70 / 100 ] filename
split -l $[ $(wc -l filename | xargs | cut -d" " -f1) * 70 / 100 ] filename
Sie können csplitbeispielsweise das erste Stück in zwei Teile teilen (mit einem beliebigen Prozentsatz) - die ersten 20% der Zeilen, das zweite Stück - die restlichen 80% der Zeilen:
csplit infile $(( $(wc -l < infile) * 2 / 10 + 1))
$(wc -l < infile): Gesamtzahl der Zeilen
2 / 10: Prozentsatz
+1: Fügen Sie eine Zeile hinzu, da sie sich csplitaufteiltup to but not including line N
Sie können jedoch nur anhand von Linien teilen.
Grundsätzlich können Sie, solange Sie die Zeilennummer über haben $(( $(wc -l < file) * 2 / 10)), jedes zeilenorientierte Werkzeug verwenden:
sed 1,$(( $(wc -l < infile) * 2 / 10))'{
w 20-infile
d
}' infile > 80-infile
oder noch cooler:
{ head -n$(( $(wc -l < infile) * 2 / 10)) > 20-infile; cat > 80-infile; } <infile
obwohl einige heads dumm sind und nicht den Standards entsprechen , funktioniert dies nicht bei allen Setups ...
{ BS=$(($(wc -c <file) * $P / 100))
dd count=1 bs="$BS" >file1; cat
} <file >file2 2>/dev/null
... sollte in diesem einfachen Fall funktionieren, da Sie sich nur einmal aufteilen - und das ist wahrscheinlich splitein wenig übertrieben. Solange die Datei durchsuchbar ist, ddwird nur eine einzige tun read()auf <stdin, und so catbleibt seine beginnen read()um jeden Punkt ddverlässt es.
Wenn die Datei groß ist, wird a count=1 bs=$big_ol_nummöglicherweise etwas unhandlich und kann mit etwas zusätzlicher, aber einfacher Shell-Mathematik ausgeblendet werden.
Ein nicht-seekable Eingang - wie aus einem Rohr - könnte Skew dd's Ergebnisse, obwohl dies auch w / GNU gehandhabt werden kann , ddsind iflag=fullblock.
Der folgende Code verwendet headund tailfunktioniert mit jedem Verhältnis (in diesem Fall 40 bis 60):
export FILE_NAME=train.vw
head -n $[ $(wc -l ${FILE_NAME}|cut -d" " -f1) * 40 / 100 ] ${FILE_NAME} > train_40.vw
tail -n +$[ ($(wc -l ${FILE_NAME}|cut -d" " -f1) * 40 / 100) + 1 ] ${FILE_NAME} > train_60.vw