我们通常从 coreutils 包开始我们的命令行之旅,它提供了处理文件、文本和 shell 操作的基本工具。这些工具是任何类 Unix 系统的基础,从使用 cp
复制文件到使用 cat
查看文本,无所不包。然而,当复杂性增加,当我们成为更有经验的用户时,我们常常发现单靠 coreutils 并不能满足更复杂的任务。
在这篇博客里,我们将探索八个来自 moreutils 的强大工具,它们能帮助我们更高效地操作命令行。
更多实用程序简介看看视频:
Moreutils 是一个包含额外命令行工具的软件包,旨在填补 coreutils 中的空缺。由 Joey Hess 创建,并在 2007 年由 GNU Linux 社区进一步扩展和完善,它提供了专门的实用工具,能够帮助您提高工作效率并简化工作流程。
虽然工具如 grep
、sed
和 awk
常用于高级文本处理,而 moreutils 提供了一套独特的命令,进一步增强了命令行的功能。
以下是一份包中所有命令的列表,在今天的博客中,我们将详细讲解其中一些命令。
**chronic**
:静默运行命令,仅在命令失败时输出。这在您只想在出现问题时收到通知的 cron 任务中特别有用。**combine**
:使用布尔操作(如 AND、OR 和 XOR)合并来自两个文件的行,提供更多对文件合并任务的控制权。**errno**
:允许您查找 errno 名称和描述,帮助您快速了解错误代码而无需查阅文档。**ifdata**
:无需解析ifconfig
的输出即可检索网络接口信息,使网络管理更加直接。**ifne**
:仅在标准输入不为空时运行程序。这在基于输入的条件执行中很有用。**isutf8**
:检查文件或标准输入是否为 UTF-8 格式,确保数据编码的一致性。**lckdo**
:在持有锁的情况下执行程序,避免其他进程同时运行相同的命令,这对于多进程环境至关重要。**mispipe**
:将两个命令连接起来,返回退出状态。**parallel**
:并行执行多个命令,充分利用多核处理器来加快批处理或测试等操作的速度。**pee**
:类似于tee
,但它不是将输出写入多个文件,而是将标准输入同时发送给多个命令,允许您一次性通过多个命令处理输入。**sponge**
:在写入文件之前先吸收标准输入,防止覆盖仍在读取的文件,这是在命令链中常见的问题。**ts**
:为输入的每一行添加时间戳,这对于实时日志记录或监控事件的时间点特别有用。**vidir**
:在文本编辑器中打开目录,使您能够像编辑文本文件中的行一样快速重命名文件。**vipe**
:在管道中插入文本编辑器,使您能够手动编辑命令输出的内容,然后再将其传递给下一个命令。**zrun**
:自动解压缩传递给命令的参数,简化处理压缩文件的过程。
在深入了解具体工具之前,先回顾一些命令行的基础知识会很有帮助。理解管道(|
)、命令替换($()
)和逻辑操作符(&&
,||
)对于有效使用coreutils和moreutils非常有用。
- 管道符(|):将一个命令的输出作为另一个命令的输入管道。例如:
ls -l | grep ".txt"
- 命令替换($()):将一个命令的输出结果作为另一个命令的参数。例如:
echo "输出今天的日期 $(date)"
- 逻辑操作符:
- && (逻辑与): 第二个命令仅在第一个命令成功的情况下才执行。
- || (逻辑或): 第二个命令仅在第一个命令失败的情况下才执行。
例子:
mkdir new_directory && cd new_directory # 创建并切换到新目录
grep "pattern" file.txt || echo "Pattern not found" # 搜索文件中的模式,若未找到则输出“未找到模式”
这样一来,我们就可以看看这个包中最实用的几个命令行工具。
combine
:用布尔逻辑来合并文件内容
combine
命令来自 moreutils 工具包,可以利用布尔运算来合并来自两个文件的行。比如说,在这种情况下,特别有用的是比较或合并来自不同来源的数据。
这里有个使用两个简单日志文件的小例子:
syslog_day1.txt
的内容如下:
错误:磁盘空间已满
警告:CPU温度过高,请注意
信息:系统已重启成功
以下是syslog_day2.txt
的内容:
错误:磁盘空间已满
警告:CPU温度过高,请注意
提示:新增用户
使用 combine
函数
- 与运算:找出两个文件中的共同行。
请把 ./syslog_day1.txt 和 ./syslog_day2.txt 合并起来
显示:
错误:磁盘空间已满
警告:CPU温度过高,请注意
- OR操作:合并两个文件中的所有行。
你可以结合 ./syslog_day1.txt 或 ./syslog_day2.txt
输出为:
错误:磁盘空间已满
警告:CPU温度过高,请注意
信息:系统已重新启动
信息:新用户已添加
- 异或运算 : 找出每个文件中独有的行。
合并 ./syslog_day1.txt 或 ./syslog_day2.txt
输出:
系统信息:系统已重启
信息:新用户已添加
- NOT 运算:查找第一个文件中但不在第二个文件中的行。
结合 ./syslog_day1.txt,不包含 ./syslog_day2.txt 的内容。
输出结果:
提示: 系统已重置
ifne
:若输出非空则执行命令
照片由 Lidia Nemiroff 拍摄,来自 Unsplash
ifne
是一个简单但强大的工具,仅当标准输出(stdout)不为空时才执行命令。这在编写脚本时特别有用,当你希望根据之前命令是否有输出来执行后续操作时。
假设我们有一个日志文件,只想在文件包含特定条目时才压缩该文件,利用前一章的示例文件。
使用ifne
命令(注:ifne
是一个特定的命令或代码片段,在编程环境中使用。如果不太常见,可以理解为“如果非空”或“如果不等”的意思。)
你可以用grep
和ifne
一起来搞定这个。
grep "Error" syslog.txt | ifne gzip syslog.txt # 这段命令用于从syslog.txt文件中查找包含"Error"的行,并在找到内容时压缩该文件。
解释一下:
grep "Error" syslog.txt
: 查找“Error”这个词,这个命令在日志文件中搜索“Error”。| ifne gzip syslog.txt
: 如果找到“Error”,这个命令将syslog.txt
文件用gzip
压缩。
如果 grep
命令在日志中找到“Error”这个词,ifne
就会把日志文件压缩一下。如果没有找到“Error”,文件就不会被压缩,保持原样。
parallel
:同时运行多个作业
照片由 Bernd 📷 Dittrich 在 Unsplash 拍摄
parallel
命令允许我们并发运行多个任务,充分使用所有 CPU 内核。这可以显著加快原本需要按顺序执行的任务。
curl
(注:curl
是一个常用的命令行工具)
想象你需要对一个网站进行多次请求,以测试其负载处理能力。而不是一一运行这些请求,我们可以用 parallel
来同时运行这些请求。
下面是我们可以这样做
seq 1 100 | parallel -j10 curl -s -o /dev/null http://example.com
这段代码的目的是并行发送100个HTTP请求到http://example.com
。通过使用parallel
命令,我们能够同时处理10个请求,从而提高效率。
-
seq 1 100
: 生成从 1 到 100 的序列,代表 100 个请求。 -
| parallel -j10
: 将后面的命令 (curl
为例) 并行运行,同时运行 10 个任务(-j10
)。 curl -s -o /dev/null http://example.com
: 向http://example.com
发送请求,但不显示任何输出(-s
表示静默模式,-o /dev/null
结果输出到空设备 (/dev/null
))。
通过这种配置,一次会向服务器发送10个curl
请求,使得模拟总共100个请求的速度显著提高。这特别适用于负载测试或需要并行运行大量相似操作的场景。
视频中,可以看到parallel
如何加速访问URL端点的速度,对比顺序访问。
pee
:用 pee 同时处理多个命令的输入
照片由 Victor Barrios 在 Unsplash 拍摄.
pee
命令与 tee
类似,但在 moreutils 中使用。pee
不是将输入数据写入多个文件,而是将标准输入流同时传递给多个命令。这在我们希望同时以不同方式处理同一输入时特别有用。
从我们之前看到的日志文件,我们想同时查找不同类型的条目,例如:“Error”、“Warning”和“Info”。我们可以用pee
来并行运行多个grep
命令,这些命令共享相同的输入。
查看 syslog.txt 文件 | pee 'grep 错误' 'grep 警告' 'grep 信息'
-
cat syslog.txt
:显示syslog.txt
文件的内容。 | pee 'grep Error' 'grep Warning' 'grep Info'
:将输出同时发送给三个grep
命令,分别查找 “Error”、“Warning” 或 “Info” 条目。
这种配置允许我们同时提取不同类型的日志条目,而不是逐个运行多个命令。每个 grep
命令处理相同的输入数据流,但使用不同的过滤条件。
sponge
: 就地替换文件内容为新的内容
这张照片由 Marjan Blan 提供,来自 Unsplash。
sponge
命令会先读取整个输入再写入文件。这可以防止在读取文件时不小心覆盖该文件的常见问题,这种情况通常发生在你尝试将输出直接重定向回正在读取的同一文件时。
假设我们有一个包含乱序数据的文件,你想把排序后的结果存回同一个文件。通常直接这样做可能会遇到问题,因为在排序还没完成之前,文件可能会被覆盖。
你可以通过以下方式使用 sponge
来避免这个问题。
sort unsorted.txt | sponge unsorted.txt
例如: sort unsorted.txt | sponge unsorted.txt
-
sort unsorted.txt
:对unsorted.txt
进行排序。 | sponge unsorted.txt
:sponge
(海绵命令) 先读取排序后的输出,再写回unsorted.txt
,确保操作安全,不会损坏文件。
ts
: 为每一行加上时间戳(ts:时间戳缩写)
ts
命令在每一行输入前添加时间戳。这在日志、监控或调试时特别有用,在这些场景中,了解每个事件的确切时间非常重要。
如果我们有一个日志文件,并且你想在每一项写入时添加时间戳,这样的话你就可以用 ts
。
tail -f /var/log/syslog | ts
tail -f /var/log/syslog
:持续显示添加到syslog文件的新行。| ts
:为每条新日志添加时间戳,显示其确切时间。
这使得很容易看出日志中的每个事件发生的时间,这对调试和监控系统非常关键。
vidir
: 在Vim的缓冲区里编辑文件和目录
照片由 Maarten van den Heuvel 拍摄,来自 Unsplash。
vidir
命令让我们能够像编辑文本文件中的行一样编辑目录中的文件名,从而使得批量重命名文件比使用mv
更快更简单。
示例:批量改名文件像
oil.nvim
和mini.files
这样的 Neovim 插件提供了更多功能特性。了解更多详情,请点击 这里。
假设你有一个文件夹,里面全是文件,你想一口气把它们重命名。
写吧
-
vidir .
:打开当前目录下的文件名至默认文本编辑器。 - 你可以在文本编辑器里直接修改这些文件名。保存并关闭编辑器后,
vidir
会自动应用这些更改,相应地重命名文件。
这是一种快速高效地批量重命名文件的方法,无需编写脚本或手动为每个文件重命名。
vipe
:编辑管道中的内容的文本编辑器 vipe
照片由 Jens Freudenau 拍摄,来自 Unsplash
vipe
命令(在管道中插入文本编辑器的命令)在管道中插入一个文本编辑器,允许我们手动编辑管道中传递的内容,然后将其发送到下一个命令。
比如我们正在筛选一些日志,想找找特定的条目,并在保存结果前做些手动修改,
grep "Error" syslog.txt | vipe | tee errors.txt
# 使用grep查找syslog.txt中包含"Error"的行,并通过vipe命令进行处理,最后将结果输出到errors.txt
-
grep "Error" syslog.txt
: 在syslog.txt
中查找所有包含“Error”的行。 -
| vipe
: 将grep
的输出通过文本编辑器打开,这样你就可以手动修改了。 | tee errors.txt
: 保存最终编辑后的输出到errors.txt
并显示出来。
这特别有用,当你需要审查或修改命令输出,在传递给管道中的下一步之前,提供了处理数据的一种灵活且互动的方式。
结尾感想我们已经探索了 moreutils 中的一些突出工具,每个工具都以独特的方式帮助我们优化了命令行工作流程。
关键不在于一次尝试使用所有工具让自己感到不知所措。相反,专注于选择一两个真正适合你工作流程的工具。不论是使用 sponge
进行安全文件编辑的便捷,还是使用 vipe
进行交互式管道编辑的灵活性,先从你觉得最有用的工具开始。
当你越来越熟悉这些工具,你可能会发现它们成为了你日常工作中不可或缺的一部分。就像任何一个出色的工具套装一样,关键是找到最适合你的工具,让它们成为你工作方式的一部分。很快,你可能会好奇没有这些工具,你以前是怎么过的。
非常感谢你花时间阅读这篇帖子。希望你觉得它既有趣又有收获。
🔗 跟我连接领英
🌐 来看看我的网站
📺 点击订阅我的我的 YouTube 频道
共同学习,写下你的评论
评论加载中...
作者其他优质文章