获取文件的百分比

获取文件的百分比

有没有一个linux命令可以返回文件的最后x%?我知道 tail 可以返回行数 (-n) 或字节数 (-c),但是如果我想获取文件的最后 25% 该怎么办?有命令可以做到这一点吗?

答案1

GNU split 几乎可以满足您的要求;给定一个文本文件in.txt,这将按照字节数(而不是行数)打印最后一个季度(4 中的第 4 部分),而不分割行:

split -n l/4/4 in.txt

这是相关文档split -n CHUNKS

CHUNKS可能是: [...]l/K/N将 N 中的第 K 个输出到 stdout,无需分割线

在问题中作为示例提到的非常具体的情况下, 4/4请求第四季度或输入文件的最后 25%。对于不是输入的 1/n 的大小,我认为 split 不能提供如此简单的解决方案。

答案2

复杂的bash+stat+bc+tail任意百分比的解:

get_last_chunk () { 
    local p=$(bc <<<"scale=2; $1/100")
    tail -c $(printf "%.0f" $(echo "$(stat -c%s $2) * $p" | bc)) "$2"
}

  • $1$2- 分别是函数的第一个和第二个参数
  • p- 以浮点数形式分配百分比值的变量(例如0.140.55
  • stat -c%s $2- 获取输入文件的实际大小(以字节为单位)
  • tail -c N $2N- 获取文件的最后一个字节

或者使用更简化的版本:

get_last_chunk () { 
    tail -c "$(($(stat -c%s - < "$2") * $1 / 100))" < "$2"))"
}

签名:get_last_chunk <percent> <filename>

样本file.txt

apples
oranges
bananas
cherries

测试用例:

get_last_chunk 17 file.txt
ries 

get_last_chunk 77 file.txt
oranges
bananas
cherries

get_last_chunk 29 file.txt
cherries

答案3

要获得最后的$1% 数量线,可移植(POSIXly):

last_percent() (
  percent=${1?}; shift
  ret=0
  for file do
    lines=$(wc -l < "$file") &&
      tail -n "$((lines * percent / 100))" < "$file" || ret=$?
  done
  exit "$ret"
)

例子:

$ seq 12 > a; printf '%s\n' aaaaaa bbbbb cccc dd > b
$ last_percent 25 a b
10
11
12
dd

对于最后$1% 的数量字节,替换wc -lwc -ctail -ntail -c但请注意,第一条输出线可能是部分的。在与上面相同的文件上,这将给出:

$ last_percent 25 a b
11
12
c
dd

使用 ksh93,您可以仅使用内置函数而不是单个 fork 来编写它,如下所示:

last_percent() (
  percent=$1; shift
  ret=0
  for file do
    command /opt/ast/bin/cat < "$file" <#((EOF*(100-percent)/100)) || ret=$?
  done
  exit "$ret"
)

使用其<#((...))查找运算符。

与以下相同zsh(除了cat不是内置的):

zmodload zsh/system zsh/stat
last_percent() {
  local percent=$1 ret=0 file n
  shift
  for file do
    {
      sysseek -w end 0 &&
        sysseek -w end ' - systell(0) * percent / 100' &&
        cat
    } < $file || ret=$?
  done
  return $ret
}

相关内容