考虑一个包含分页 ASCII 控制字符“换页”($'\f') 的纯文本文件:
alpha\n
beta\n
gamma\n\f
one\n
two\n
three\n
four\n
five\n\f
earth\n
wind\n
fire\n
water\n\f
请注意,每个页面都有随机数量的行。
需要一个 bash 例程,从包含分页 ASCII 控制字符的文本文件中返回给定行号的页码。
经过长时间研究解决方案,我终于遇到了这段代码:
function get_page_from_line
{
local nline="$1"
local input_file="$2"
local npag=0
local ln=0
local total=0
while IFS= read -d $'\f' -r page; do
npag=$(( ++npag ))
ln=$(echo -n "$page" | wc -l)
total=$(( total + ln ))
if [ $total -ge $nline ]; then
echo "${npag}"
return
fi
done < "$input_file"
echo "0"
return
}
但不幸的是,这种解决方案在某些情况下被证明非常慢。
有更好的解决办法吗?
Thanks!
使用的想法read -d $'\f'
然后计算行数就很好了。
这个版本可能显得不优雅:如果nline
大于或等于文件中的行数,则文件被读取两次。
尝试一下,因为它超级快:
function get_page_from_line ()
{
local nline="${1}"
local input_file="${2}"
if [[ $(wc -l "${input_file}" | awk '{print $1}') -lt nline ]] ; then
printf "0\n"
else
printf "%d\n" $(( $(head -n ${nline} "${input_file}" | grep -c "^"$'\f') + 1 ))
fi
}
的表演awk比上面的 bash 版本更好。awk是为此类文本处理而创建的。
尝试一下这个经过测试的版本:
function get_page_from_line ()
{
awk -v nline="${1}" '
BEGIN {
npag=1;
}
{
if (index($0,"\f")>0) {
npag++;
}
if (NR==nline) {
print npag;
linefound=1;
exit;
}
}
END {
if (!linefound) {
print 0;
}
}' "${2}"
}
When \f
遇到时,页码增加。
NR
是当前行号。
----
对于历史,还有另一个 bash 版本。
此版本仅使用内置命令来计算当前页面中的行数。
The speedtest.sh
您在评论中提供的信息显示它有点超前(大约 20 秒),这使得它相当于您的版本:
function get_page_from_line ()
{
local nline="$1"
local input_file="$2"
local npag=0
local total=0
while IFS= read -d $'\f' -r page; do
npag=$(( npag + 1 ))
IFS=$'\n'
for line in ${page}
do
total=$(( total + 1 ))
if [[ total -eq nline ]] ; then
printf "%d\n" ${npag}
unset IFS
return
fi
done
unset IFS
done < "$input_file"
printf "0\n"
return
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)