如何使用"头部"和"尾部"打印文件的特定行

14 unix shell arguments tail unix-head

我想说一个文件的输出行5-10,作为传入的参数.

我怎么能使用head,并tail做到这一点?

其中,firstline = $2lastline = $3filename = $1.

运行它应该如下所示:

./lines.sh filename firstline lastline
Run Code Online (Sandbox Code Playgroud)

fed*_*qui 28

head -n XX # <-- print first XX lines
tail -n YY # <-- print last YY lines
Run Code Online (Sandbox Code Playgroud)

如果你想要20到30行,这意味着你需要11行从20开始并在30结束:

head -n 30 file | tail -n 11
# 
# first 30 lines
#                 last 11 lines from those previous 30
Run Code Online (Sandbox Code Playgroud)

也就是说,你先获得第一30行,然后选择最后一行11(即,30-20+1).

所以在你的代码中它将是:

head -n $3 $1 | tail -n $(( $3-$2 + 1 ))
Run Code Online (Sandbox Code Playgroud)

基于firstline = $2,lastline = $3,filename = $1

head -n $lastline $filename | tail -n $(( $lastline -$firstline + 1 ))
Run Code Online (Sandbox Code Playgroud)


sfs*_*man 17

除了fedorquiKent给出的答案,您还可以使用单个sed命令:

#! /bin/sh
filename=$1
firstline=$2
lastline=$3

# Basics of sed:
#   1. sed commands have a matching part and a command part.
#   2. The matching part matches lines, generally by number or regular expression.
#   3. The command part executes a command on that line, possibly changing its text.
#
# By default, sed will print everything in its buffer to standard output.  
# The -n option turns this off, so it only prints what you tell it to.
#
# The -e option gives sed a command or set of commands (separated by semicolons).
# Below, we use two commands:
#
# ${firstline},${lastline}p
#   This matches lines firstline to lastline, inclusive
#   The command 'p' tells sed to print the line to standard output
#
# ${lastline}q
#   This matches line ${lastline}.  It tells sed to quit.  This command 
#   is run after the print command, so sed quits after printing the last line.
#   
sed -ne "${firstline},${lastline}p;${lastline}q" < ${filename}
Run Code Online (Sandbox Code Playgroud)

或者,为了避免任何外部使用,如果您使用的是最新版本的bash(或zsh):

#! /bin/sh

filename=$1
firstline=$2
lastline=$3

i=0
exec <${filename}  # redirect file into our stdin
while read ; do    # read each line into REPLY variable
  i=$(( $i + 1 ))  # maintain line count

  if [ "$i" -ge "${firstline}" ] ; then
    if [ "$i" -gt "${lastline}" ] ; then
      break
    else
      echo "${REPLY}"
    fi
  fi
done
Run Code Online (Sandbox Code Playgroud)


Ken*_*ent 6

试试这个单行:

awk -vs="$begin" -ve="$end" 'NR>=s&&NR<=e' "$f"
Run Code Online (Sandbox Code Playgroud)

在上面的行:

$begin is your $2
$end is your $3
$f is your $1
Run Code Online (Sandbox Code Playgroud)

  • @ user2232423好的,您可以自由选择最适合您的解决方案.我们对"简单"有不同的定义.**a)**你需要两个头部和尾部的过程.awk只是一个过程.**b)**awk也可以在达到你的'$ 3'之后退出处理(如果你有一个怪物文件我在答案中没有这样做).**c)**awk可以验证你的'$ 2 $ 3',例如,如果`$ 2> $ 3`则根本不处理该文件.你必须为你的头/尾编写额外的脚本.awk更简单,不是吗? (3认同)
  • 我更喜欢使用头和尾来保持简单, (2认同)

Dad*_*ado 5

将其保存为“ script.sh ”:

#!/bin/sh

filename="$1"
firstline=$2
lastline=$3
linestoprint=$(($lastline-$firstline+1))

tail -n +$firstline "$filename" | head -n $linestoprint
Run Code Online (Sandbox Code Playgroud)

没有错误处理(为了简单起见),因此您必须按如下方式调用脚本:

./script.sh yourfile.txt 第一行 最后一行

$ ./script.sh yourfile.txt 5 10
Run Code Online (Sandbox Code Playgroud)

如果您只需要 yourfile.txt 中的“10”行:

$ ./script.sh yourfile.txt 10 10
Run Code Online (Sandbox Code Playgroud)

请确保:(firstline > 0) AND (lastline > 0) AND (firstline <= lastline)