有没有一种“规范”的方式来作到这一点? 我一直在使用head -n | tail -1
head -n | tail -1
能够达到目的,可是我一直在想是否有一个Bash工具专门从文件中提取一行(或一系列行)。 数组
“规范”是指一个程序,其主要功能就是这样作。 bash
# print line number 52 sed '52!d' file
sed有用的单行脚本 ide
使用awk
能够很是快: 函数
awk 'NR == num_line' file
若是为true,则执行awk
的默认行为: {print $0}
。 工具
若是您的文件碰巧很大,则最好在读取所需行后exit
。 这样能够节省CPU时间。 ui
awk 'NR == num_line {print; exit}' file
若是要从bash变量中提供行号,能够使用: spa
awk 'NR == n' n=$num file awk -v n=$num 'NR == n' file # equivalent
这个问题被标记为Bash,这是Bash(≥4)的处理方式:使用带有-s
(跳过)和-n
(计数)选项的mapfile
。 unix
若是您须要获取文件file
的第42行: code
mapfile -s 41 -n 1 ary < file
此时,您将拥有一个数组ary
,该数组的字段包含file
行(包括结尾的换行符),在此咱们跳过了前41行( -s 41
),并在读取了一行( -n 1
以后)中止了-n 1
)。 这就是第42行。 要打印出来: get
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内置函数!
要使用带有变量做为行号的sed打印第n行:
a=4 sed -e $a'q:d' file
这里的-e标志用于将脚本添加到要执行的命令。
对于大文件,最快的解决方案始终是tail | head,前提是两个距离:
S
E
众所周知。 而后,咱们能够使用如下代码:
mycount="$E"; (( E > S )) && mycount="+$S" howmany="$(( endline - startline + 1 ))" tail -n "$mycount"| head -n "$howmany"
多少只是所需的行数。