有没有一个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.14
或0.55
)stat -c%s $2
- 获取输入文件的实际大小(以字节为单位)tail -c N $2
N
- 获取文件的最后一个字节
或者使用更简化的版本:
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 -l
为wc -c
和tail -n
。tail -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
}