有没有一种“规范”的方式来做到这一点? 我一直在使用head -n | tail -1
head -n | tail -1
可以达到目的,但是我一直在想是否有一个Bash工具专门从文件中提取一行(或一系列行)。
“规范”是指一个程序,其主要功能就是这样做。
#1楼
# print line number 52
sed '52!d' file
#2楼
使用awk
可以非常快:
awk 'NR == num_line' file
如果为true,则执行awk
的默认行为: {print $0}
。
替代版本
如果您的文件碰巧很大,则最好在读取所需行后exit
。 这样可以节省CPU时间。
awk 'NR == num_line {print; exit}' file
如果要从bash变量中提供行号,可以使用:
awk 'NR == n' n=$num file
awk -v n=$num 'NR == n' file # equivalent
#3楼
这个问题被标记为Bash,这是Bash(≥4)的处理方式:使用带有-s
(跳过)和-n
(计数)选项的mapfile
。
如果您需要获取文件file
的第42行:
mapfile -s 41 -n 1 ary < file
此时,您将拥有一个数组ary
,该数组的字段包含file
行(包括结尾的换行符),在此我们跳过了前41行( -s 41
),并在读取了一行( -n 1
之后)停止了-n 1
)。 这就是第42行。 要打印出来:
printf '%s' "${ary[0]}"
如果您需要一定范围的行,请说范围为42–666(含),并说您不想自己做数学,并在stdout上打印它们:
mapfile -s $((42-1)) -n $((666-42+1)) ary < file
printf '%s' "${ary[@]}"
如果您也需要处理这些行,则存储尾随的换行符并不是很方便。 在这种情况下,请使用-t
选项(修剪):
mapfile -t -s $((42-1)) -n $((666-42+1)) ary < file
# do stuff
printf '%s\n' "${ary[@]}"
您可以使用一个函数为您执行此操作:
print_file_range() {
# $1-$2 is the range of file $3 to be printed to stdout
local ary
mapfile -s $(($1-1)) -n $(($2-$1+1)) ary < "$3"
printf '%s' "${ary[@]}"
}
没有外部命令,只有Bash内置函数!
#4楼
要使用带有变量作为行号的sed打印第n行:
a=4
sed -e $a'q:d' file
这里的-e标志用于将脚本添加到要执行的命令。
#5楼
对于大文件,最快的解决方案始终是tail | head,前提是两个距离:
- 从文件的开头到起始行。 让我们称之为
S
- 从最后一行到文件末尾的距离。 成为
E
众所周知。 然后,我们可以使用以下代码:
mycount="$E"; (( E > S )) && mycount="+$S"
howmany="$(( endline - startline + 1 ))"
tail -n "$mycount"| head -n "$howmany"
多少只是所需的行数。
https://unix.stackexchange.com/a/216614/79743中的更多详细信息
来源:oschina
链接:https://my.oschina.net/u/3797416/blog/3156407