Bash工具从文件获取第n行

有没有一种“规范”的方式来作到这一点? 我一直在使用head -n | tail -1 head -n | tail -1能够达到目的,可是我一直在想是否有一个Bash工具专门从文件中提取一行(或一系列行)。 数组

“规范”是指一个程序,其主要功能就是这样作。 bash


#1楼

# print line number 52
sed '52!d' file

sed有用的单行脚本 ide


#2楼

使用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

#3楼

这个问题被标记为Bash,这是Bash(≥4)的处理方式:使用带有-s (跳过)和-n (计数)选项的mapfileunix

若是您须要获取文件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内置函数!


#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中的更多详细信息

相关文章
相关标签/搜索