Eu criei esta função simples que faz exatamente o que eu quero fazer.
# $1 percentage as a decimal fraction; e.g., 0.75 = 75%
# increase decimal points to get more accurate rounding 0.755
# $2 input file
# $3 output file top percentage
# $4 output file bottom percentage
# e.g., 70% split = 70% top + 30% bottom = 100%
function file_prec_split () {
TOTAL=$(wc -l $2 | cut -d" " -f 1)
TOPPERC='echo "scale=0; ${TOTAL} * $(printf %.2f $1)" | bc -l | cut -d"." -f 1'
head -n $TOPPERC $2 > $3
tail -n +$TOPPERC $2 > $4
}
echo "'seq 1 100'" > 1to100.txt
file_prec_split 0.30 1to100.txt 30top.txt 70bot.txt
Se você quiser fazer algumas divisões mais complexas, 40% / 20% / 40%, então você pode executar a função várias vezes. Você precisa agrupar e depois executar as divisões. Combine os primeiros 40% e 20% em 60%. Executar 60% / 40% primeiro e depois 40% / 20%.
Pode ser necessário fazer algumas contas simples para descobrir como essa divisão deve ser calculada.
60% (40% / 20%) precisa ser normalizado para 100% Aqui está como eu calculei essa divisão
0.4/0.6 = .66
0.2/0.6 = .33
(60% / 40%)
file_prec_split 0.60 1to100.txt 60top.txt 40bot.txt
(40% / 20%) = 60%
0.4/0.6 = .66
file_prec_split 0.66 60top.txt 40top.txt 20mid.txt
Achei útil o seguinte ao fazer os cálculos no Linux. As casas decimais extras ajudam o arredondamento a ser mais preciso ao fazer a divisão.
SUP_PERCENT=$(printf %.2f $(echo "scale=4; 0.4/0.6" | bc -l))
file_prec_split $SUP_PERCENT 60top.txt 40top.txt 20top.txt