Jak mogę podzielić plik tekstowy na 70% i 30% za pomocą polecenia split?
Jak mogę podzielić plik tekstowy na 70% i 30% za pomocą polecenia split?
Odpowiedzi:
Poniższe polecenia będą działać dla wartości procentowych powyżej 50% (jeśli chcesz podzielić tylko na dwa pliki), szybkie i brudne podejście.
1) podział 70% na podstawie linii
split -l $[ $(wc -l filename|cut -d" " -f1) * 70 / 100 ] filename
2) podziel 70% na podstawie bajtów
split -b $[ $(wc -c filename|cut -d" " -f1) * 70 / 100 ] filename
split -l $[ $(wc -l filename | xargs | cut -d" " -f1) * 70 / 100 ] filename
Możesz użyć csplit
do podzielenia na dwie części (używając dowolnego procentu) np. Pierwsza część - pierwsze 20% linii, druga część - pozostałe 80% linii:
csplit infile $(( $(wc -l < infile) * 2 / 10 + 1))
$(wc -l < infile)
: całkowita liczba linii
2 / 10
: procent
+1
: dodaj jedną linię, ponieważ csplit
dzieliup to but not including line N
Możesz jednak dzielić tylko na podstawie linii.
Zasadniczo, o ile masz numer linii $(( $(wc -l < file) * 2 / 10))
, możesz użyć dowolnego narzędzia zorientowanego na linię:
sed 1,$(( $(wc -l < infile) * 2 / 10))'{
w 20-infile
d
}' infile > 80-infile
lub nawet chłodniejsze:
{ head -n$(( $(wc -l < infile) * 2 / 10)) > 20-infile; cat > 80-infile; } <infile
chociaż niektóre head
są głupie i nie są zgodne ze standardami, więc nie będzie działać na wszystkich konfiguracjach ...
{ BS=$(($(wc -c <file) * $P / 100))
dd count=1 bs="$BS" >file1; cat
} <file >file2 2>/dev/null
... powinien działać w tym prostym przypadku, ponieważ dzielisz tylko raz - i prawdopodobnie split
jest to trochę przesada. Tak długo, jak plik jest widoczny, dd
wykona tylko jeden read()
na nim <stdin
, a więc cat
pozostanie rozpocząć read()
od momentu, w którym dd
go opuści.
Jeśli plik jest duży, to count=1 bs=$big_ol_num
może stać się trochę nieporęczny i można go zablokować za pomocą dodatkowej - ale prostej - matematyki powłoki.
Wejście niż możliwy do przeszukania - jak z rury - może pochylać dd
"S wyniki, chociaż mogą być również traktowane jako w / GNU dd
jest iflag=fullblock
.
Poniższy kod używa head
i tail
działa z dowolnym współczynnikiem (w tym przypadku 40 do 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