Я создал эту простую функцию, которая делает именно то, что я хочу.
# $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
Если вы хотите сделать более сложные разбиения, например, 40% / 20% / 40%, вы можете запустить функцию несколько раз.
Вам нужно сгруппировать, а затем запустить разделение.
Объедините первые 40% и 20% в 60%.
Выполните сначала 60% / 40%, а затем 40% / 20%.
Возможно, вам понадобится выполнить простую математику, чтобы выяснить, как рассчитать это деление.
60% (40% / 20%) нужно нормализовать до 100%. Вот как я рассчитал этот сплит
0,4/0,6 = 0,66
0,2/0,6 = 0,33
(60% / 40%)
file_prec_split 0.60 1to100.txt 60top.txt 40bot.txt
(40% / 20%) = 60%
0,4/0,6 = 0,66
file_prec_split 0.66 60top.txt 40top.txt 20mid.txt
Я нашел следующее полезным при выполнении расчетов в Linux. Дополнительные десятичные разряды помогают с округлением быть более точным при выполнении разделения.
SUP_PERCENT=$(printf %.2f $(echo "scale=4; 0.4/0.6" | bc -l))
file_prec_split $SUP_PERCENT 60top.txt 40top.txt 20top.txt