head 命令详解与参数实测(Ubuntu 22.04)

head 全参数实测:默认前 10 行、-n N、-c N 按字节、-n -K 负数参数除末尾 K 行、旧式 -5 写法、多文件 ==> 头,Ubuntu 22.04 coreutils 8.32 全部回显实测。

Linux命令Linux系统UbuntuUbuntu 22.04命令行文本处理2026/10/15

head 命令详解与参数实测(Ubuntu 22.04)

目标:全面掌握 head 的取头能力——默认前 10 行、-n N 指定行数、-c N 按字节截取、-n -K「除末尾 K 行」的负数参数、旧式 -5 写法、多文件输出的 ==> 文件 <== 头,全部命令与回显已在 Ubuntu 22.04(head 属 GNU coreutils 8.32)实测通过。

一、环境信息

本节记录实测环境与演示数据,便于读者对照复现。head 与 tail 是一对:head 取头部、tail 取尾部,参数体系几乎对称。环境信息里同时列出演示目录与测试文件。

  • 操作系统:Ubuntu 22.04.5 LTS(x86_64)
  • head 版本:GNU coreutils 8.32(软件包 coreutils 8.32-4.1ubuntu1.4,见 2.3 实测)
  • 演示目录:/root/demo/head/
  • 测试数据:30 行长文本 long.txt、5 行短文件 a.txt 与 b.txt(用于多文件演示)

二、命令概览

2.1 语法与测试数据准备

帮助原文给出的语法是 head [OPTION]... [FILE]...,职责一句话:Print the first 10 lines of each FILE to standard output(输出每个文件的前 10 行)。核心参数就两组:-n 按行、-c 按字节,两者都支持 [-]NUM 形式——带负号时语义反转成「除末尾 NUM 之外全部输出」,这是 head 容易被忽略的能力。

准备演示数据——30 行长文本与两个 5 行短文件:

printf "head demo line %02d\n" $(seq 1 30) > /root/demo/head/long.txt
printf "alpha-1\nalpha-2\nalpha-3\nalpha-4\nalpha-5\n" > /root/demo/head/a.txt
printf "bravo-1\nbravo-2\nbravo-3\nbravo-4\nbravo-5\n" > /root/demo/head/b.txt

验证数据就绪——long.txt 30 行、a.txt/b.txt 各 5 行:

$ wc -l /root/demo/head/long.txt /root/demo/head/a.txt /root/demo/head/b.txt
 30 /root/demo/head/long.txt
  5 /root/demo/head/a.txt
  5 /root/demo/head/b.txt
 40 total

2.2 --help 全量回显

head 的帮助不长,包含参数表、NUM 倍数后缀说明,原文完整收录:

Usage: head [OPTION]... [FILE]...
Print the first 10 lines of each FILE to standard output.
With more than one FILE, precede each with a header giving the file name.

With no FILE, or when FILE is -, read standard input.

Mandatory arguments to long options are mandatory for short options too.
  -c, --bytes=[-]NUM       print the first NUM bytes of each file;
                             with the leading '-', print all but the last
                             NUM bytes of each file
  -n, --lines=[-]NUM       print the first NUM lines instead of the first 10;
                             with the leading '-', print all but the last
                             NUM lines of each file
  -q, --quiet, --silent    never print headers giving file names
  -v, --verbose            always print headers giving file names
  -z, --zero-terminated    line delimiter is NUL, not newline
      --help     display this help and exit
      --version  output version information and exit

NUM may have a multiplier suffix:
b 512, kB 1000, K 1024, MB 1000*1000, M 1024*1024,
GB 1000*1000*1000, G 1024*1024*1024, and so on for T, P, E, Z, Y.
Binary prefixes can be used, too: KiB=K, MiB=M, and so on.

GNU coreutils online help: <https://www.gnu.org/software/coreutils/>
Report any translation bugs to <https://translationproject.org/team/>
Full documentation <https://www.gnu.org/software/coreutils/head>
or available locally via: info '(coreutils) head invocation'

💡 说明:两个值得先划的重点——其一,-c/-n 的 NUM 支持倍数后缀(K=1024、M=1024×1024、b=512 等),head -c 1K 直接取前 1KiB;其二,多文件时默认打印 ==> 文件名 <== 头(可用 -q 关掉、-v 强制打开)。两者都在正文实测或引用。

2.3 版本确认

确认 head 的归属与版本:

$ head --version | head -1
head (GNU coreutils) 8.32

输出 head (GNU coreutils) 8.32,即本文全部回显均来自 coreutils 8.32 的实现。

三、参数逐项实测

3.1 无参数:默认输出前 10 行

不带任何参数,head 输出文件前 10 行。对 30 行的 long.txt 执行:

$ head /root/demo/head/long.txt
head demo line 01
head demo line 02
head demo line 03
head demo line 04
head demo line 05
head demo line 06
head demo line 07
head demo line 08
head demo line 09
head demo line 10

只输出第 1~10 行,第 11 行起的 20 行被丢弃。这个「默认 10」来自 POSIX 约定,head 与 tail 的默认值相同。

💡 提示:文件不足 10 行时 head 全量输出、不报错;读一个未知大小的文件,先 head 扫一眼开头是最快的安全动作。

💡 技术拓展:取文件开头 N 行不止 head 一种写法,横向对比——

方式写法特点
headhead -n N 文件专用取头,读到 N 行即停,支持 -c 字节与 -n -K 负数语义(本文主角)
sedsed -n '1,Np' 文件全文逐行扫描后筛选,大文件上效率低于 head
awkawk 'NR<=N' 文件可顺带做字段加工,取行只是附带能力

只为取头就用 head;需要边取边加工再考虑 sed/awk。

3.2 -n N:指定行数

-n N 把 10 改成任意行数。取前 3 行:

$ head -n 3 /root/demo/head/long.txt
head demo line 01
head demo line 02
head demo line 03

取前 12 行:

$ head -n 12 /root/demo/head/long.txt
head demo line 01
head demo line 02
head demo line 03
head demo line 04
head demo line 05
head demo line 06
head demo line 07
head demo line 08
head demo line 09
head demo line 10
head demo line 11
head demo line 12

帮助原文里 -n 的完整形式是 --lines=[-]NUM——方括号里的负号就是 3.4 要实测的「除末尾 K 行」用法。

💡 提示:管道里 head 常用来「截断上游输出」,例如 ps aux | head -5 看进程列表前几行;head -n 1 单取第一行(表头)也是脚本里的高频写法。

3.3 -c N:按字节截取

-c N 不按行、按字节数截取,经常得到「半行」输出。取前 20 字节(head demo line 01\n 共 18 字节,再取下一行前 2 字节):

$ head -c 20 /root/demo/head/long.txt
head demo line 01
he

输出第一行完整 + 下一行开头的 he,直观展示了字节截断不认行边界。取前 60 字节:

$ head -c 60 /root/demo/head/long.txt
head demo line 01
head demo line 02
head demo line 03
head d

三行完整(18×3=54 字节)加第 4 行前 6 字节 head d。-c 支持 2.2 提到的倍数后缀,head -c 1K 文件 即取前 1024 字节。

💡 提示:二进制文件抽样检查头几字节(魔数)用 -c:head -c 4 文件 | od -c 能看到真实字节,这是判断文件真实类型的老办法。

3.4 -n -K:除末尾 K 行(负数参数)

-n 后给负数时语义反转:输出「除末尾 K 行之外」的全部内容。30 行文件,head -n -28 即去掉末尾 28 行、留前 2 行:

$ head -n -28 /root/demo/head/long.txt
head demo line 01
head demo line 02

head -n -2 去掉末尾 2 行、留前 28 行(输出节选,实测首尾):

$ head -n -2 /root/demo/head/long.txt
head demo line 01
head demo line 02
head demo line 03
head demo line 04
head demo line 05
(中间略:第 6~27 行依序输出)
head demo line 26
head demo line 27
head demo line 28

管道场景同样成立——5 行输入去掉末尾 2 行:

$ printf "p1\np2\np3\np4\np5\n" | head -n -2
p1
p2
p3

head -n -2 的价值在「行数未知但明确要砍掉尾部几行」:比如文件末尾 2 行是汇总行/落款,处理正文时用 -n -2 一步剥离,无需先 wc -l 算总数。

💡 提示:帮助原文写作 --lines=[-]NUM,负号写进参数里(-n -2),不是 -- -2;-c 也支持同样的负数语义(除末尾 K 字节)。

3.5 旧式 -5 写法

历史遗留的短选项写法:-N(数字直接跟在连字符后)等价于 -n N。head -5:

$ head -5 /root/demo/head/long.txt
head demo line 01
head demo line 02
head demo line 03
head demo line 04
head demo line 05

head -12 同样取前 12 行:

$ head -12 /root/demo/head/long.txt
head demo line 01
head demo line 02
head demo line 03
head demo line 04
head demo line 05
head demo line 06
head demo line 07
head demo line 08
head demo line 09
head demo line 10
head demo line 11
head demo line 12

head -5 与 head -n 5 输出完全一致。旧式写法在老脚本里常见,且 tail 同样支持;新脚本建议统一用 -n N,语义更明确,还能与 -n -K 的负数形式并存不歧义。

💡 提示:head -5 这种写法是 obsolete 语法,与 -c 混用或跟以数字开头的文件名组合时可能产生歧义,跨平台脚本里优先 -n。

四、实战示例

4.1 多文件输出与 ==> 文件 <== 头

head 跟多个文件时,每个文件前打印 ==> 文件名 <== 分隔头。两个 5 行文件(各不足 10 行,全量输出):

$ head /root/demo/head/a.txt /root/demo/head/b.txt
==> /root/demo/head/a.txt <==
alpha-1
alpha-2
alpha-3
alpha-4
alpha-5

==> /root/demo/head/b.txt <==
bravo-1
bravo-2
bravo-3
bravo-4
bravo-5

三个文件各取 2 行,分隔头逐个出现:

$ head -n 2 /root/demo/head/a.txt /root/demo/head/b.txt /root/demo/head/long.txt
==> /root/demo/head/a.txt <==
alpha-1
alpha-2

==> /root/demo/head/b.txt <==
bravo-1
bravo-2

==> /root/demo/head/long.txt <==
head demo line 01
head demo line 02

分隔头让多文件输出依然能对上号。用 grep 统计分隔头个数即可核对文件数:

$ head -n 2 /root/demo/head/a.txt /root/demo/head/b.txt | grep -c "==> "
2

输出 2,对应两个文件。帮助原文注明的 -q(永不打印头)与 -v(总是打印头)可在多文件场景切换这一行为——单文件时默认不打印头,需要的话 head -v 文件 强制显示。

💡 提示:这个 ==> 文件 <== 格式是 coreutils 家族(head/tail)的通用约定,写解析脚本时可按它切分多文件输出;不想让它出现就加 -q。

五、注意事项与常见问题

Q1:head 默认为什么是 10 行?能不能改? 10 行来自 POSIX 规范对 head/tail 的约定,无法通过环境变量修改默认值;每次用 -n N 显式指定,或用旧式 head -N(见 3.5)。

Q2:head -n -2 和 head -n 2 只差一个负号,会不会搞混? 语义完全相反:-n 2 取前 2 行,-n -2 取除末尾 2 行的全部(见 3.4 实测)。记法上「负号 = 从尾部扣除」,与 -c -K 同理。老脚本若出现 head -2(旧式写法)只等于 -n 2,没有负数语义。

Q3:head -c 20 输出最后半行,管道下游会出问题吗? 会。字节截断不补换行(见 3.3 实测末尾 he 无换行),下游按行处理的工具(grep/awk)会把「半行 + 上游残留」当数据处理。文本场景优先 -n,确需 -c 时下游用 tr -d '\n' 之类按字节处理。

Q4:head 对二进制文件安全吗? 安全。head 按字节读取原样输出,不会修改内容;但终端可能因二进制字节乱码或响铃,配合 od -c、xxd 查看更稳妥(见 3.3 提示)。-z 参数可把行分隔符从 \n 换成 NUL,配合 find -print0 处理特殊文件名。

Q5:多文件时 ==> 文件 <== 头干扰了脚本解析,怎么去掉? 加 -q(--quiet)关闭分隔头(见 2.2 帮助原文);反之单文件也想看到文件名时加 -v。多文件是默认打印头的唯一触发条件。

Q6:head -5 文件名以数字开头 会怎样? 旧式 -N 写法后跟数字开头的文件名会被解析歧义(-5 后面的部分难以判定边界),coreutils 会按 obsolete 语法尽力解析但可读性差;这类场景统一改用 head -n 5 ./文件名 规避。

六、参考链接