Linux系统篇--重定向与文件操作命令
系列文章目录
Linux系统篇--常用指令
Linux系统篇--重定向与文件操作命令(本篇)
前言
在上一篇文章中,我们掌握了 pwd、ls、cd、mkdir、touch、rm 等一批最基础的指令,学会了在文件系统里"定位"和"创建删除"。但真正用起来你会发现,光是会创建文件还不够------怎么往文件里写内容?怎么快速查看一个几万行的日志?怎么把一个命令的结果保存下来? 这些才是日常使用中更高频的需求。
本篇聚焦这条主线:先讲两个"输出内容"的命令 echo 和 printf,再引出 Linux 中极其重要的重定向 机制(输入、输出、追加),然后系统梳理一批查看文件的命令------cat、tac、more、less、head、tail,以及查手册的 man。最后补充文件操作三件套 cp、mv 和时间命令 date。
这些命令组合起来,就是一整套"往文件里写、从文件里读、按需查看、按需搬运"的完整能力,务必熟练。
一、echo ------ 最常用的输出命令
echo 用于把参数输出到终端,是 Shell 中使用频率最高的命令之一。
1. 基本用法
echo "hello world"
hello world
输出字符串并自动换行。不加引号也可以,但如果内容含空格,建议加引号更稳妥:
echo hello world
hello world
2. echo -n ------ 不换行输出
默认 echo 输出后会自动换行,-n 可以取消这个换行:
echo -n "hello"
echo " world"
hello world
两行输出连在了一起,这就是 -n 的效果。
3. echo -e ------ 开启转义
默认情况下,echo 会把 \n 当普通字符原样输出。加上 -e 才会解析转义字符:
echo -e "第一行\n第二行\t制表符"
第一行
第二行 制表符
常用转义符:
| 转义符 | 含义 |
|---|---|
\n |
换行 |
\t |
制表符(Tab) |
\\ |
输出一个反斜杠 |
\a |
响铃 |
\b |
退格 |
4. 三种引号的区别
这是容易踩坑的地方,一定要分清:
echo 'hello $USER' # 单引号:原样输出,不解析变量
hello $USER
echo "hello $USER" # 双引号:解析变量
hello student
echo `whoami` # 反引号:命令替换,先执行命令再输出结果
student
- 单引号:强引用,里面的一切都当普通文本;
- 双引号 :弱引用,变量
$xxx、命令替换仍然生效; - 反引号 :把命令的执行结果嵌入输出(现代写法推荐
$(命令))。
二、printf ------ 格式化输出
echo 简单直接,但遇到"按格式对齐输出"就力不从心了------这时用 printf。它来自 C 语言,按格式串输出。
1. 基本用法
printf "格式串" 参数1 参数2 ...
示例:
printf "姓名:%s,年龄:%d\n" "张三" 20
姓名:张三,年龄:20
2. 常用格式符
| 格式符 | 含义 |
|---|---|
%s |
字符串 |
%d |
十进制整数 |
%f |
浮点数 |
%c |
单个字符 |
%.2f |
保留两位小数的浮点数 |
%5d |
宽度为 5、右对齐的整数 |
%-5d |
宽度为 5、左对齐的整数 |
printf "%-10s|%5d\n" "apple" 12
apple | 12
3. 与 echo 的对比
二者的核心差别有两点,务必记住:
| 对比项 | echo | printf |
|---|---|---|
| 换行 | 默认自动换行 | 默认不换行 ,须显式写 \n |
| 格式控制 | 无 | 支持格式化对齐 |
| 转义 | 需加 -e |
默认解析转义符 |
| 适用场景 | 简单输出 | 需要对齐、格式化的输出 |
最容易踩的坑:printf 不会自动换行。 忘了写 \n,后续输出就会全都挤在同一行。
三、重定向
重定向是 Linux 中一个极其重要的机制。默认情况下,命令的输出送到屏幕、输入来自键盘;重定向可以改变这两个"默认通道",把输出写进文件、或从文件读取输入。
1. 输出重定向 > ------ 覆盖写入
echo "hello" > test.txt
cat test.txt
hello
> 把 echo 本应送到屏幕的内容改送到了 test.txt。
重点提醒:> 是覆盖! 文件原有内容会被全部清空替换:
echo "hello" > test.txt
echo "world" > test.txt # 覆盖了上面的内容
cat test.txt
world
哪怕文件里有几千行内容,一条 > 也会瞬间清空。这是新手最容易造成数据丢失的操作。
2. 追加重定向 >> ------ 追加写入
想保留原内容、只在末尾加新内容,就用 >>:
echo "hello" > test.txt
echo "world" >> test.txt # 追加,不清空原内容
cat test.txt
hello
world
> 与 >> 的区别是本节的命脉:单箭头覆盖,双箭头追加。
3. 输入重定向 < ------ 从文件读入
< 把命令的输入来源从键盘改为文件:
cat < test.txt # 相当于把 test.txt 的内容"喂"给 cat
hello
world
4. 标准输入、输出、错误
Linux 每个进程默认打开三个通道,用文件描述符表示:
| 描述符 | 名称 | 默认去向 |
|---|---|---|
0 |
标准输入 stdin | 键盘 |
1 |
标准输出 stdout | 屏幕 |
2 |
标准错误 stderr | 屏幕 |
所以 > 其实是 1> 的简写。区分正常输出和错误输出很有用:
ls /notexist > out.txt 2> err.txt # 正确输出进 out.txt,错误信息进 err.txt
常用组合:
命令 > all.txt 2>&1 # 把标准输出和标准错误都写入同一个文件
命令 &> all.txt # 同上,bash 提供的简写
命令 2> /dev/null # 丢弃错误信息(扔进"黑洞")
/dev/null 是 Linux 的"黑洞文件",写进去的内容会被直接丢弃,常用于屏蔽不需要的输出。
5. 利用 cat 配合追加重定向写入内容
这是实际操作中非常好用的一个组合。cat 不加文件名时,会从标准输入读取内容并输出------配合追加重定向,就能把键盘输入的内容写进文件:
cat >> notes.txt
今天学习了重定向
Ctrl + D # 按 Ctrl+D 结束输入
现在 notes.txt 末尾就多了这一行。如果要一次写入多行,可以用多行重定向(Here Document):
cat >> notes.txt << EOF
第一行内容
第二行内容
EOF
<< EOF 表示"后续内容一直读到 EOF 这一行为止",中间的换行会被完整保留。这个写法在写脚本、生成配置文件时极为常用,比逐行 echo >> 整洁得多。
也可以用 cat 合并多个文件并追加到目标文件:
cat a.txt b.txt >> all.txt # 把 a、b 的内容依次追加到 all.txt 末尾
四、查看文件的命令
写进去的内容总得能看。下面这几个命令各有分工。
1. cat ------ 一次性显示全部内容
cat test.txt
cat(concatenate)最基本的用途就是把文件内容全部打印到屏幕。适合内容较少的文件------文件几百行以上时,内容会刷屏而过,来不及看。
常用选项:
cat -n test.txt # 显示行号(含空行)
cat -b test.txt # 只给非空行编号
cat -s test.txt # 把连续多个空行压缩成一个
cat -A test.txt # 显示不可见字符(如 $ 表示行尾)
cat 还有个经典用法------合并文件:
cat a.txt b.txt > c.txt # 把两个文件拼接成一个新文件
2. tac ------ 倒序显示
tac 就是 cat 反过来写,功能也是反过来------按行倒序输出:
cat test.txt
第一行
第二行
第三行
tac test.txt
第三行
第二行
第一行
注意:tac 是以行为单位倒序,不是把每个字符倒过来。查看日志时想从最后一条往上看,它很好用。
3. more ------ 分页显示(只能向下)
more test.txt
内容多时,more 会一屏一屏地显示。它的操作键比较"复古":
| 操作 | 作用 |
|---|---|
| 空格 | 向下翻一屏 |
| 回车 | 向下翻一行 |
b |
向上翻一屏(部分实现支持) |
q |
退出 |
more 的局限:只能向下翻,翻过去就回不来了,也不支持搜索。
4. less ------ 分页显示(可上下翻,推荐)
less 是 more 的增强版------"less is more"。功能更强,也是实际使用中最推荐的查看工具:
less test.txt
常用操作键:
| 操作 | 作用 |
|---|---|
空格 / f |
向下翻一屏 |
b |
向上翻一屏 |
↑ / ↓ |
上下移动一行 |
g / G |
跳到文件开头 / 末尾 |
/关键词 |
向下搜索 |
n / N |
跳到下一个 / 上一个匹配 |
q |
退出 |
less 不会一次性把整个文件读进内存,打开大文件也很快 ,这一点比 cat、more 都有优势。
5. 小结对比
| 命令 | 特点 | 适用场景 |
|---|---|---|
cat |
一次全部输出,不带分页 | 小文件、拼接文件 |
tac |
按行倒序输出 | 倒着看日志 |
more |
分页,只能向下 | 简单浏览 |
less |
分页,可上下翻、可搜索 | 查看大文件(推荐) |
五、head 与 tail ------ 只看头尾
很多时候我们并不需要看全部内容,只想看开头几行或结尾几行。
1. head ------ 看开头
head test.txt # 默认显示前 10 行
head -n 5 test.txt # 显示前 5 行
head -5 test.txt # 简写,效果相同
head -c 20 test.txt # 按字节:显示前 20 个字节
2. tail ------ 看结尾
tail test.txt # 默认显示后 10 行
tail -n 5 test.txt # 显示后 5 行
tail -5 test.txt # 简写
tail 有个 head 没有的杀手级选项-------f(follow):
tail -f /var/log/syslog
它会持续跟踪文件末尾 ,文件有新增内容就实时打印出来。这是排查线上问题的标准手段 ------开着 tail -f,日志一有新动静立刻就能看到。想退出按 Ctrl + C。
3. 组合使用
两个命令可以用管道串起来,取"中间的一段":
head -n 20 test.txt | tail -n 5 # 取第 16~20 行
先用 head 取出前 20 行,再用 tail 取这 20 行里的后 5 行,合起来就是第 16 到第 20 行。这个套路在处理大文件时很实用。
六、man ------ 随身手册
命令太多记不住怎么办?man 就是 Linux 自带的说明书。
man ls
它会显示 ls 的完整手册:命令说明、所有选项、示例等。进入后操作方式和 less 类似:
| 操作 | 作用 |
|---|---|
空格 / b |
上下翻屏 |
/关键词 |
搜索 |
n |
下一个匹配 |
q |
退出手册 |
如果记不清命令的名字,可以用 -k 按关键词搜索:
man -k copy # 搜索所有与 copy 相关的手册
懒得看完整手册、只想知道有哪些选项时,直接试试 --help:
ls --help
记住一个原则:遇到不认识的命令或选项,第一反应就应该是 man 它。 这比搜索引擎更快、更准确。
七、cp ------ 复制
cp(copy)用于复制文件或目录。
1. 基本用法
cp 源文件 目标文件
示例:
cp a.txt b.txt # 复制 a.txt 为 b.txt
cp a.txt /tmp/ # 复制 a.txt 到 /tmp 目录下(保持文件名)
2. 复制目录要加 -r
直接 cp 一个目录会报错,必须加递归选项:
cp -r project project_bak # 递归复制整个目录
3. 常用选项
| 选项 | 作用 |
|---|---|
-r |
递归复制目录 |
-i |
覆盖前询问确认 |
-f |
强制覆盖,不询问 |
-v |
显示复制过程 |
-p |
保留属性(权限、时间等) |
-a |
归档模式,等价于 -dpr,最完整 |
cp -rv project project_bak # 复制并显示每一步
cp -a project project_bak # 完整保留所有属性
特别注意:cp 遇到同名文件会直接覆盖,不留痕迹。 建议给 cp 加 -i,或使用 alias cp='cp -i'。
八、mv ------ 移动与重命名
mv(move)一个命令顶两个功能,区别只在目标位置。
1. 重命名
源和目标在同一个目录 时,mv 就是重命名:
mv old.txt new.txt
2. 移动
目标是一个已存在的目录 时,mv 就是移动:
mv a.txt /tmp/ # 把 a.txt 移动到 /tmp
mv a.txt /tmp/b.txt # 移动并顺便改名
mv dir1 /tmp/ # 移动目录,不需要 -r
和 cp 的重要区别:mv 移动目录不需要 -r,因为它是直接改路径,不涉及递归复制。
3. 常用选项
mv -i a.txt b.txt # 覆盖前询问
mv -f a.txt b.txt # 强制覆盖
mv -v a.txt b.txt # 显示过程
mv 同样会覆盖同名文件。另外要注意:mv 在同一分区内是"改个名字",瞬间完成;跨分区移动则要真正拷贝数据,耗时会明显变长。
九、date ------ 时间与时间戳
1. 显示当前时间
date
Wed Oct 14 22:49:09 CST 2026
2. 格式化输出
用 + 接格式串,自定义显示形式:
date +%Y-%m-%d
2026-10-14
date "+%Y-%m-%d %H:%M:%S"
2026-10-14 22:49:09
常用格式符:
| 格式符 | 含义 |
|---|---|
%Y |
四位年份 |
%m |
月份(01--12) |
%d |
日期(01--31) |
%H |
小时(00--23) |
%M |
分钟 |
%S |
秒 |
%s |
Unix 时间戳 |
3. 时间戳
Unix 时间戳 指从 1970 年 1 月 1 日 00:00:00 UTC 起,到现在的总秒数------一个不管时区、不管格式,全球唯一的整数。
date +%s
1792027749
时间戳反查日期,用 -d @ 的形式:
date -d @1792027749
Wed Oct 14 22:49:09 CST 2026
date -d @1792027749 +%Y-%m-%d
2026-10-14
为什么非要用时间戳? 因为它是一个纯粹的数字:比较大小即比较先后、做差即得到秒数间隔、排序天然有序、存储不占空间。所以日志记录、监控告警、程序打时间点,底层用的都是时间戳,只在展示时才转成人类可读的格式。
4. 时间戳的实际用法
echo "任务开始:$(date +%s)" >> task.log # 把时间戳追加进日志
配合前面学的重定向,就能拼出一条带时间戳的日志记录------这也是后面写 Shell 脚本时的常见套路。
十、综合小实战
把本篇的知识串起来,做一件事:创建一个带时间戳的日志文件,并实时监控它。
第一步,用输入重定向创建初始内容:
cat > app.log << EOF
2026-10-14 22:49:09 服务启动
2026-10-14 22:49:10 等待请求
EOF
第二步,用追加重定向 + 时间戳追加新记录:
echo "$(date '+%Y-%m-%d %H:%M:%S') 收到新请求" >> app.log
第三步,开两个终端,一个持续追加,一个用 tail -f 实时监控:
tail -f app.log
新追加的记录会立刻出现在屏幕上。至此,echo / printf 负责生成内容,重定向负责写入,cat 负责拼接,head / tail / less 负责查看,man 负责查漏------一条完整的命令流水线就搭起来了。
总结
本篇的核心可以归为两大块记忆:
重定向: > 覆盖写入、>> 追加写入、< 从文件读入、2> 单独处理错误、&> 合并输出与错误、/dev/null 丢弃输出。牢记"单箭头覆盖、双箭头追加",这是最容易出错也最需要警惕的一点。
文件查看与操作: echo(输出,-n 不换行、-e 解析转义)、printf(格式化输出,注意不会自动换行);查看用 cat(小文件)、tac(倒序)、more(只能向下)、less(可上下翻+搜索,推荐)、head(看头)、tail(看尾,-f 实时监控);man 是你的随身手册。文件操作用 cp(复制目录要 -r)、mv(一个命令同时负责移动和重命名);date 负责时间与时间戳,date +%s 取时间戳、date -d @ 反查日期。
这些命令单独看都很简单,真正的威力在于组合 ------head | tail 取中间段,cat >> file << EOF 批量写文件,tail -f 配重定向做实时日志。多在自己的终端里敲几遍,把命令练成条件反射,后面的 Shell 脚本、权限管理、进程控制才能顺理成章。
后续我们将继续深入 Linux 的相关知识,敬请期待。
本文是《Linux系统篇》系列的第二篇,如需命令速查表或练习环境,可在评论区留言。