bash – 如何按百分比分割文件.线?

前端之家收集整理的这篇文章主要介绍了bash – 如何按百分比分割文件.线?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
如何按百分比分割文件.线?

假设我想将文件分成3个部分(60%/ 20%/ 20%部分),我可以手动执行此操作,-_-:

  1. $wc -l brown.txt
  2. 57339 brown.txt
  3.  
  4. $bc <<< "57339 / 10 * 6"
  5. 34398
  6. $bc <<< "57339 / 10 * 2"
  7. 11466
  8. $bc <<< "34398 + 11466"
  9. 45864
  10. bc <<< "34398 + 11466 + 11475"
  11. 57339
  12.  
  13. $head -n 34398 brown.txt > part1.txt
  14. $sed -n 34399,45864p brown.txt > part2.txt
  15. $sed -n 45865,57339p brown.txt > part3.txt
  16. $wc -l part*.txt
  17. 34398 part1.txt
  18. 11466 part2.txt
  19. 11475 part3.txt
  20. 57339 total

但我相信有更好的方法

有一个实用程序将行号作为参数,这些行号应成为每个相应新文件的第一个:csplit.这是它的 POSIX version的包装:
  1. #!/bin/bash
  2.  
  3. usage () {
  4. printf '%s\n' "${0##*/} [-ks] [-f prefix] [-n number] file arg1..." >&2
  5. }
  6.  
  7. # Collect csplit options
  8. while getopts "ksf:n:" opt; do
  9. case "$opt" in
  10. k|s) args+=(-"$opt") ;; # k: no remove on error,s: silent
  11. f|n) args+=(-"$opt" "$OPTARG") ;; # f: filename prefix,n: digits in number
  12. *) usage; exit 1 ;;
  13. esac
  14. done
  15. shift $(( OPTIND - 1 ))
  16.  
  17. fname=$1
  18. shift
  19. ratios=("$@")
  20.  
  21. len=$(wc -l < "$fname")
  22.  
  23. # Sum of ratios and array of cumulative ratios
  24. for ratio in "${ratios[@]}"; do
  25. (( total += ratio ))
  26. cumsums+=("$total")
  27. done
  28.  
  29. # Don't need the last element
  30. unset cumsums[-1]
  31.  
  32. # Array of numbers of first line in each split file
  33. for sum in "${cumsums[@]}"; do
  34. linenums+=( $(( sum * len / total + 1 )) )
  35. done
  36.  
  37. csplit "${args[@]}" "$fname" "${linenums[@]}"

在要拆分的文件名称之后,它采用拆分文件的大小相对于它们的总和的比率,即,

  1. percsplit brown.txt 60 20 20
  2. percsplit brown.txt 6 2 2
  3. percsplit brown.txt 3 1 1

都是等价的.

与问题案例类似的用法如下:

  1. $percsplit -s -f part -n 1 brown.txt 60 20 20
  2. $wc -l part*
  3. 34403 part0
  4. 11468 part1
  5. 11468 part2
  6. 57339 total

但编号从零开始,并且没有txt扩展名. GNU version支持–suffix格式选项,该选项允许.txt扩展,并且可以添加到接受的参数中,但这需要比getopts更精细的解析它们.

这个解决方案适用于非常短的文件(将两行分成两行),繁重的工作由csplit本身完成.

猜你在找的Bash相关文章