6113 字
31 分钟
Linux基础(10-1):特殊符号完全通配符、正则与重定向的实战手册

Linux命令行的强大之处,很大程度上源于其丰富的特殊符号体系。对于刚接触 Linux 的新手小白来说,面对满屏的 >、|、*、$ 往往会感到像在看天书。但实际上,这些看似高深的符号,就像是搭积木的“接口”,它们能把一个个简单的基础命令,拼接成极其强大的自动化流水线。

本文将为你系统、通俗地讲解 Linux 中最常用的特殊符号。我们不仅会深入浅出地剖析通配符和正则表达式,还会配以大量“接地气”的生活比喻和可以直接在电脑上敲出来的实战案例。不管你是用 Ubuntu、CentOS 还是国产操作系统,这篇指南都能帮你从“只会死记硬背”跨越到“真正理解命令行”!

一、基础控制符号:命令行的“粘合剂”与“水管”#

在 Linux 世界里,万物皆文件,命令的执行结果也是数据的流动。基础控制符号的作用,就是控制这些数据的流向,把不同的命令像水管一样连接起来。

1.1 重定向符号(★★★★★ 核心必学)#

【大白话解释】 如果把命令当成一个“加工厂”:

  • 标准输入(stdin):工厂的进货口,默认从你的键盘读取输入。
  • 标准输出(stdout):工厂的正门出货口,默认把正常结果打印到你的屏幕上。
  • 标准错误(stderr):工厂的废品/报错出口,默认也会把报错信息打印到屏幕上。

重定向,就是改变默认的进出货口。比如,把原本要显示在屏幕上的结果,直接塞进一个文件里存起来。

符号名字大白话作用新手小白必敲示例
>覆盖重定向像擦掉黑板重新写,清空文件原内容再写入echo "你好" > 1.txt(1.txt的内容变成”你好”)
>>追加重定向像在日记本末尾写新日记,保留原内容在末尾加echo "世界" >> 1.txt(末尾多出一行”世界”)
2>错误重定向(覆盖)专门把报错信息收集到文件里(覆盖)ls /随便乱敲的目录 2> error.log
2>>错误重定向(追加)专门把报错信息收集到文件里(追加)ls /随便乱敲 2>> error.log
&>全部重定向不管是对是错,所有输出统统打包塞进文件ping baidu.com &> all.log
<输入重定向让命令去文件里读内容,而不是等你敲键盘cat < 1.txt(相当于把1.txt的内容喂给cat)

多行输入重定向(高级但好用): 当你需要一次性往文件里写很多行内容时,可以用 << EOF。

Terminal
# 一次性把这三行内容写入 script.sh 中
cat > script.sh << EOF
#!/bin/bash
echo "Hello World"
date
EOF
NOTE关于黑洞设备 /dev/null:命令行的垃圾桶

有时候命令会产生一大堆没用的日志,看着心烦。Linux 提供了一个无底洞 /dev/null,任何扔进去的东西都会瞬间消失,常用于保持屏幕清爽。 ::

Terminal
# 场景:只想知道命令有没有报错,正常的输出我不想看(丢进垃圾桶)
ls /etc > /dev/null
# 场景:我什么都不想看,不管是正常结果还是报错,全部闭嘴(极度安静模式)
ping -c 3 baidu.com &> /dev/null

1.2 管道符 |(★★★★★ 灵魂符号)#

【大白话解释】 管道符就是一条流水线传送带。它把左边命令的“正常输出结果”,直接当做右边命令的“输入原料”。

新手实战场景: 假设你在找系统里的进程,但进程太多了满屏都是。

Terminal
# 1. 先用 ps 查看系统里所有运行的程序
# 2. 结果太多了看不过来?用管道符 '|' 送给 grep,只过滤出带有 'nginx' 的行
ps aux | grep nginx
# 多重管道(流水线):看文件 -> 找特定内容 -> 统计行数
cat access.log | grep "404" | wc -l

(小白提示:遇到长长的结果不要怕,用 | 传给下一个命令去慢慢过滤筛选!)

1.3 管道的黄金搭档 xargs(★★★★★ 突破管道限制)#

【大白话解释】 管道符 | 虽然强大,但它有个致命弱点:它只负责把左边命令的输出传到右边命令的「标准输入」里。然而,绝大多数命令(如 ls、rm、cp、mkdir 等)根本不读标准输入,它们只认跟在后面的「命令行参数」。 xargs 的核心作用就是当个**“转换器”**:接住管道传过来的文本,把它拆分成一个个参数,强行拼到后面的命令上执行。

管道 vs xargs 核心对比(新手极易踩坑):

Terminal
# ❌ 错误:rm 不读标准输入,管道传过去的文件名完全没用
find . -name "*.log" | rm
# ✅ 正确:xargs 把文件名转成 rm 的参数,等价于执行了 rm a.log b.log
find . -name "*.log" | xargs rm

新手必学的 4 类高频场景:

① 配合 find 批量操作文件(最高频) find 负责筛选文件,xargs 负责接力执行具体操作。

Terminal
# 批量删除空文件
find . -type f -empty | xargs rm
# 批量修改目录权限
find . -type d | xargs chmod 755

② 批量处理文本清单 假设 list.txt 里每行存了一个想创建的目录名:

Terminal
# 逐行转成 mkdir 的参数,批量建目录
cat list.txt | xargs mkdir

③ 配合 grep 在多个文件里搜内容 直接管道传给 grep,它只会搜索传过来的纯文本;加上 xargs,它是把文件名当参数,让 grep 去打开这些文件搜内容!

Terminal
# 在所有 py 文件里,搜索 "error" 关键词
find . -name "*.py" | xargs grep "error"

④ 带占位符的复杂操作(-I 参数) 如果参数不是放在命令末尾,而是要插到中间,可以用 -I {} 做占位符。

Terminal
# 把找到的空文件,统一复制到 /tmp/backup/ 目录
find . -type f -empty | xargs -I {} cp {} /tmp/backup/
CAUTION文件名带空格的致命坑

如果文件名里有空格或特殊字符,普通 xargs 会把空格当成分隔符,导致把一个完整文件名劈成两半报错。 安全写法(搭配 -print0 和 -0):

Terminal
find . -type f -empty -print0 | xargs -0 ls -lh

(-print0 让 find 输出时用 null 字符分隔,-0 让 xargs 用 null 字符读取,完美兼容所有合法文件名) ::

[!TIP] 快速判断口诀

  • 命令是操作文件本身(删、复制、改权限、看属性等,如 rm/cp/mkdir/ls)→ 必须加 xargs
  • 命令是处理文本内容(排序、统计、替换、筛选等,如 cat/wc/sort/awk)→ 直接用管道 |

1.4 命令替换符号:$() 与 反引号 `#

【大白话解释】 相当于俄罗斯套娃或者数学里的括号。系统会优先执行符号里面的命令,把结果变成普通的文字,再交给外面的命令使用。

在 Linux 中,有两种符号可以实现这个功能:$() 和 反引号 `(键盘左上角 Esc 下面的按键)。

基础用法对比(两者效果完全一样):

Terminal
# 场景:我想创建一个文件夹,名字是今天的日期
# 写法一:使用 $() 【现代推荐写法】
mkdir backup_$(date +%F)
# 写法二:使用反引号 【老教程及老脚本常见写法】
mkdir backup_`date +%F`
# 最终电脑实际执行的都是:mkdir backup_2026-07-14
CAUTION为什么现在全世界都劝你放弃反引号?

作为新手,你必须能看懂反引号(因为公司里的老旧脚本全都是它),但强烈建议你自己写代码时只用 $()。原因有二:

  1. 极易混淆:反引号 ` 和单引号 ' 在很多终端字体下长得太像了,排错时能把眼睛看瞎。
  2. “套娃”嵌套简直是噩梦:当你需要把命令一层层嵌套时,$() 非常直观,而反引号需要极其反人类的转义符。
Terminal
# 场景:查看 '通过 which 找到的 docker 命令' 的所属文件类型
# ✅ $() 嵌套,清爽易读
file $(which docker)
# 如果再套一层也毫无压力: echo $(file $(which docker))
# ❌ 反引号嵌套,需要加反斜杠转义,否则直接报错
file `which docker`
# 如果再套一层,简直是灾难: echo `file \`which docker\``

::

1.5 逻辑运算符 && 和 ||#

【大白话解释】 让命令行具有“思考判断”的能力,常用于连招。

  • &&(逻辑与):“如果前面成功了,才接着做后面”。
  • ||(逻辑或):“如果前面失败了,才接着做后面”。
Terminal
# 场景1 (&&):进入 test 目录,如果成功进去了,才创建 1.txt(防止在错误的地方建文件)
cd test && touch 1.txt
# 场景2 (||):如果找不见 config.yml 文件,那就用 touch 创建一个
ls config.yml || touch config.yml
# 场景3 (组合拳):下载 -> 编译 -> 安装,任何一步报错,立马停止,防止错上加错
./configure && make && make install

1.6 后台运行符号 &#

【大白话解释】 相当于雇了个隐形的后台小助手。有些命令要跑很久(比如下载大文件),如果你在终端里干等,什么都干不了。在命令最后加个 &,它就会自己去后台默默干活,你可以继续敲别的命令。

Terminal
# 普通后台运行(注意:如果你关掉这个黑框终端,任务可能会中断)
cp -r /data /backup &
# 彻底的后台运行(nohup + &):即使你关掉电脑去睡觉,服务器也会一直跑
nohup cp -r /data /backup &> backup.log &
# 后台管家指令
jobs # 查看当前有哪些小助手在后台干活
fg %1 # 把 1 号小助手拉回前台,看着它干活

二、通配符(★★★★★ 找文件的超级外挂)#

【大白话解释】 什么是“通配符”?你可以把它想象成扑克牌里的“癞子(Joker)”,它可以变出你想要的任何牌。在 Linux 里,当你想操作一堆文件,却不想(或者懒得)把它们的名字一个一个全敲出来时,通配符就能帮你“一网打尽”。

⚠️ 新手请把这句话刻在脑子里: 通配符只管“找文件的名字”,绝对不管“文件里面写了什么内容”!(找内容那是下一节正则表达式干的活,千万别搞混)。

2.1 基础匹配符号:四大金刚#

下面我们来逐一拆解最常用的四个基础通配符。假设我们有一个文件夹,里面有这些文件:a.txt, b.txt, 1.txt, img_1.png, img_10.png, log_2026.log。

① 星号 *:无敌匹配王(0个或无数个字符)#

它是最常用的符号,意思是**“不管这里有什么,也不管有几个字符,甚至是空着什么都没有,我全都要”**。

Terminal
# 场景1:找出所有以 .txt 结尾的文件
ls *.txt
# 结果:a.txt, b.txt, 1.txt 会被列出来
# 场景2:找出名字里包含 "img" 的所有文件
ls *img*
# 结果:img_1.png, img_10.png 会被列出来
# 场景3:删除所有名字以 "log_" 开头的文件(危险操作,慎用!)
rm -f log_*

② 问号 ?:严格的单座沙发(恰好1个字符)#

它比星号严格得多。一个 ? 必须且只能代表一个任意字符,不能多也不能少。

Terminal
# 场景1:找名字只有一个字符的 txt 文件
ls ?.txt
# 结果:a.txt, b.txt, 1.txt (注意:不会匹配 10.txt,因为 10 是两个字符)
# 场景2:精准匹配 img_ 后接1个数字的图片
ls img_?.png
# 结果:只匹配 img_1.png,绝不会匹配 img_10.png

③ 中括号 []:多选一的菜单(指定范围内的1个字符)#

中括号里可以写一堆字符,它的意思是**“只要在这个括号里的,随便挑一个都行,但也只能挑一个”**。

Terminal
# 场景1:只找 a.txt 或者 b.txt
ls [ab].txt
# 场景2:找名字是数字的 txt 文件(用连字符 - 表示范围)
ls [0-9].txt
# 结果:1.txt(如果存在 2.txt 到 9.txt 也会被找出来)
# 场景3:找名字是小写字母的 txt 文件
ls [a-z].txt

④ 排除符号 [^] 或 [!]:黑名单(除了括号里的,其他都要)#

在括号里面加上 ^ 或者 !,意思就完全反过来了。

Terminal
# 场景:找出名字【不是】数字的 txt 文件
ls [^0-9].txt
# 结果:a.txt, b.txt 会被列出来,1.txt 会被无视

2.2 大括号扩展 {}:键盘寿命拯救者#

如果你觉得前面四个已经很强了,那大括号绝对能让你惊掉下巴。它不是用来“找”已有文件的,而是用来**“批量生成”**名字组合序列的。学会它,你的敲击键盘次数会成倍减少!

新手实战场景与原理解析:

Terminal
# 场景1:瞬间创建 100 个连续的测试文件
touch test_file_{1..100}.txt
# 原理:{1..100} 会自动展开成 1, 2, 3 一直到 100。你可以去文件夹里看,100个文件瞬间建好!
# 场景2:批量操作特定后缀的文件
ls *.{jpg,png,gif}
# 原理:这相当于同时执行了 ls *.jpg、ls *.png 和 ls *.gif。
# 场景3:【运维老司机最爱】极限速度备份文件!
cp /etc/nginx/nginx.conf{,.bak}
# 原理分析:大括号里以逗号分隔,左边是空的,右边是 .bak。
# 电脑执行时会把它展开成:cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
# 也就是“把原文件 复制成 原文件.bak”。再也不用把长长的文件名敲两遍了!
# 场景4:一键生成复杂的工程目录层级
mkdir -p my_project/{src,bin,doc,test,logs/{access,error}}
# 这条命令会同时建好 src, bin, doc 等文件夹,甚至还在 logs 下面嵌套建了 access 和 error 文件夹。
WARNING新手常见踩坑警告 💣
  1. 隐身术失效:星号 * 默认看不见隐藏文件(在 Linux 中以 . 开头的文件叫隐藏文件,比如 .bashrc)。如果你想匹配隐藏文件,必须显式地写出来,比如 ls .*。
  2. “找不到就装傻”:如果你敲了 ls *.pdf,但是当前目录里根本没有 pdf 文件,Linux 默认不会报错说“找不到文件”,而是会死心眼地把 *.pdf 当成一个叫这名字的普通字符串去处理。在写复杂脚本时,这经常会导致奇怪的报错(比如提示 “Cannot access *.pdf”)。 ::

三、基础正则表达式(★★★★★ 找文本内容的火眼金睛)#

【大白话解释】 如果说通配符是在“找书本的名字”,那正则表达式(Regular Expression,简称 Regex)就是在**“翻开书本,找里面写的特定句子”。它是专门用来处理文本内容**的终极武器。

正则表达式主要和 grep(文本搜索)、sed(文本替换)、awk(文本分析)这“三剑客”配合使用。新手刚看正则可能会觉得像乱码,但只要掌握了它的核心规律,你就能在一秒钟内从百万行的日志里,精准抓出你需要的那一行。

3.1 核心元字符字典:看懂“乱码”的密码本#

在正则的世界里,符号的含义和刚才讲的通配符完全不同!请暂时忘掉通配符的规则。

元字符名字大白话作用常用搭配面试/实战常考示例
^行首锚点必须是这行的开头^rootgrep "^root" /etc/passwd(找必须以 root 开头的行)
$行尾锚点必须是这行的结尾bash$grep "bash$" /etc/passwd(找必须以 bash 结尾的行)
^$空白行开头紧接着结尾,啥也没有-v "^$"grep -v "^$" config.ini(把文件里的空白行全部删掉不看)
.万能单字符占位符,代表任意 1 个字符r..tgrep "r..t" file.txt(匹配 root, r12t, r__t 等)
*数量乘号把它前面那个字符,复制 0 次或无数次ro*tgrep "ro*t" file.txt(匹配 rt, rot, root, rooooooot 等)
.*万能胶水任意长度的任意字符(类似通配符的*)a.*bgrep "a.*b" text(匹配 a 和 b 之间夹着任意东西的行)
\照妖镜(转义)去掉符号的魔法,变回普通的符号本身\.grep "\.com" domains.txt(只找普通的 .com,而不是万能字符.com)
\{n\}次数限制器严格规定前面的字符必须出现 n 次o\{2\}grep "o\{2\}" text.txt(规定字母 o 必须连续出现2次)

3.2 生产环境正则实战:新手跟我敲#

理论太枯燥,我们直接上真实工作中最常用的几个场景。

场景 1:看配置文件时,去掉那些烦人的注释和空行 Linux 里的配置文件动不动就几百行,其中 80% 都是带 # 号的注释和空行。用正则可以瞬间还你一个清爽的有效配置。

Terminal
# 第一步:grep -v 是“反向过滤”(不要包含匹配项的行)。先去掉以 # 开头的行
# 第二步:通过管道符,继续去掉空行(^$ 代表空行)
grep -v "^#" /etc/ssh/sshd_config | grep -v "^$"
# 结果:几百行的文件瞬间只剩下几十行真正生效的配置,极其舒服!

场景 2:在茫茫日志中,精准提取 IP 地址(IPv4) 服务器被攻击了?你想从日志里把黑客的 IP 找出来。一个 IP 的格式是 数字.数字.数字.数字。

Terminal
# 拆解:
# [0-9] 代表找数字。
# \{1,3\} 代表前面的数字最少出现1次,最多出现3次(比如 8 是一次,192 是三次)。
# \. 是因为 . 默认是万能字符,必须用 \ 把它打回原形,变成普通的英文句号。
grep "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" /var/log/messages

场景 3:抓取包含手机号码的行 假设你有一个几十万行的 Excel 转成的 CSV 文件,你想把里面所有包含大陆手机号的行都找出来。

Terminal
# 大陆手机号规律:11位数字。第一位是1,第二位是3-9,后面跟着9个任意数字。
grep "1[3-9][0-9]\{9\}" user_data.csv
# 如果你的文件里混杂着 :spoiler[13812345678] 这样的号码,它也能一秒钟给你全揪出来!

[!TIP] 新手感悟 看到这里你可能会觉得:“这反斜杠 \ 怎么这么多啊?看起来好丑好难写!” 没错,这就是“基础正则表达式”的痛点。为了解决这个问题,聪明的程序员发明了下面的“扩展正则表达式”。

四、扩展正则表达式(★★★★ 告别反斜杠的进化版)#

【大白话解释】 基础正则表达式虽然厉害,但它有个致命的弱点:太喜欢用反斜杠 \ 来“转义”了!比如你想表示大括号 {} 或者逻辑或 |,在基础正则里必须写成 \{\} 和 \|。一旦规则长了,满屏都是斜杠,连写代码的人自己都看不懂。

为了拯救大家的眼睛,**扩展正则表达式(Extended Regex)**诞生了。它取消了那些烦人的反斜杠要求,引入了更符合人类直觉的符号。

TIP一秒开启扩展模式

想在 grep 中使用扩展正则,只需要加上 -E 参数即可(即 grep -E)。 (老手可能会教你用 egrep,但请注意:egrep 在最新的 Linux 系统中已经被标记为“过时废弃”,请全面拥抱 grep -E!) ::

4.1 扩展专属元字符:更好用的新武器#

在开启了 -E 之后,你解锁了以下几个极其好用的符号:

符号名字大白话作用示例说明
+至少一次前面的字符至少要出现 1 次(不能没有)grep -E "a+"(匹配 a, aa, aaa,但不匹配没有 a 的空)
?可有可无前面的字符要么出现 1 次,要么干脆没有grep -E "https?"(匹配 http 或 https)
|逻辑或左右两边满足一个就行(二选一)grep -E "cat|dog"(找包含 cat 或者 dog 的行)
()打包分组把它当成数学里的括号,把几个字符绑在一起grep -E "(abc)+"(匹配 abc, abcabc,而不是 abccc)
{n,m}优雅次数前面的字符出现 n 到 m 次(彻底告别 \{\})grep -E "o{2,4}"(匹配 2 到 4 个 o,写法清爽多了)

4.2 扩展正则重构对比:没有对比就没有伤害#

我们来看看,同一个需求,用“基础正则”和“扩展正则”写出来有什么区别。你会立刻爱上扩展正则的。

场景 1:匹配网站日志里的 4xx 和 5xx 报错状态码

Terminal
# ❌ [基础正则] 满屏斜杠,看着辣眼睛,极容易写错
grep " 4[0-9]\{2\} \| 5[0-9]\{2\} " access.log
# ✅ [扩展正则] 像说话一样顺滑 (4或者5开头,后面跟着2个数字)
grep -E " (4|5)[0-9]{2} " access.log

场景 2:抓取各种主流后缀的域名 假设你有一个包含无数网址的文本,你想把 .com、.cn、.org 结尾的域名全提出来。

Terminal
# 用扩展正则简直是小菜一碟
grep -E "[a-zA-Z0-9_-]+\.(com|cn|org|net)" domains.list
# 拆解:
# [a-zA-Z0-9_-]+ 代表域名的前缀(字母数字横杠),+号表示至少要有1个字符
# \. 依然是转义的普通句号
# (com|cn|org|net) 就是多选一的菜单

五、通配符 vs 正则表达式:绝不搞混的终极指南#

这是所有 Linux 新手甚至部分老手都会踩的超级大坑!请把下面这个对比表打印出来贴在屏幕上:

灵魂拷问🐧 通配符 (Wildcards)🕷️ 正则表达式 (Regex)
到底用来干嘛?匹配文件名(找外壳,比如找 *.txt)匹配文件内容(找内涵,比如找包含手机号的行)
是谁在解析它?Bash Shell 自身(Linux 命令行本身)grep / sed / awk 等专门的文本处理软件
最容易搞混的 *代表任意数量的任意字符(相当于万能牌)代表把前面的字符复制 0 次或无数次(是个数量词)
最容易搞混的 .它就是一个普普通通的英文句号它是代表任意 1 个字符的万能牌
应该配合谁使用?ls, cp, mv, rm, find 等文件管理命令grep, sed, awk, vim 搜索等内容管理命令
CAUTION典型翻车现场(新手必看)

❌ 错误示范 1: ls ^file 或 rm *.txt$ 很多新手学了正则后,觉得自己无所不能,试图用 ls ^file 来找以 file 开头的文件。大错特错! ls 和 rm 根本听不懂正则。这里必须用通配符:ls file*。

❌ 错误示范 2: grep "*.txt" access.log 试图用通配符的语法去文件里搜索内容,结果什么都搜不到。在正则里,* 必须跟在某个字符后面。 ::

六、进阶避坑与最佳实践清单(老司机秘籍)#

掌握了符号,不代表能写出好代码。这里总结了四个能让你看起来像“入行五年的老司机”的习惯:

1. 组合嵌套重定向:拒绝啰嗦#

当你既不想看到正常输出,也不想看到报错时。

  • ❌ 新手写法:> /dev/null 2>&1(太长,而且很难理解)
  • ✅ 老手写法:&> /dev/null(干净利落,一步到位)

2. 极速备份法:肌肉记忆#

在修改 Nginx、MySQL、Redis 等关键配置文件前,必须备份。

  • ❌ 新手写法:cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak(容易敲错,浪费时间)
  • ✅ 老手写法:敲完文件路径后,直接补上 {,.bak}。这是不加班的秘密武器。

3. 隔离正则边界:给正则穿上防弹衣#

在写 grep 等命令时,一定要用双引号 " " 或单引号 ' ' 把你的正则表达式包起来! 如果不包起来,Linux 终端(Shell)可能会自作聪明地以为你在写通配符,提前把正则符号给“吃掉”,导致出现极其诡异的报错。

  • ✅ 正确姿势:grep -E "(4|5)[0-9]{2}" log.txt

4. 分解长管道:拯救接盘侠#

当你的流水线(管道符 |)超过 3 个时,千万不要把它挤在一行里。使用 \(续行符)将其断行编写。

format_log.sh
# 优秀的复杂过滤排版演示
cat /var/log/nginx/access.log \
| grep -E " 50[0-4] " \
| awk '{print $1}' \
| sort \
| uniq -c \
| sort -nr \
| head -n 10
# 这样写,不管是你自己明天回来看,还是交接给新同事,都能一眼看懂每一步在干什么。

如果你想要长期根治脚本中的符号语法混乱,强烈推荐使用自动化扫描工具评估你的脚本质量:

koalaman
/
shellcheck
Waiting for api.github.com...
00K
0K
0K
Waiting...
Linux基础(10-1):特殊符号完全通配符、正则与重定向的实战手册
https://www.6ixblog.site/posts/linux-basic-10-1/
作者
Licwic
发布于
2025-01-11
许可协议
CC BY-NC-SA 4.0