在 BASH 的管线操作中,有很多实用的小工具可以帮我们快速处理文本数据,这些工具可以帮我们完成数据选取、排序、转换、分割等常见操作,极大提升文本处理的效率。下面我们就来逐一梳理这些常用命令的用法。
一、选取命令:cut、grep
选取命令的作用是将一段数据经过分析后,取出我们想要的部分,这类命令通常是针对一行一行的信息来进行分析的。
cut
cut 可以将一行信息的某一段切出来,处理的信息以行为单位,非常适合处理有固定格式的文本。
语法格式:
cut \-d\&\#39;分隔字符\&\#39; \-f fields:用于有特定分隔字符的场景cut \-c 字符区间:用于排列整齐的信息
参数说明:
\-d:后面接分隔字符,与\-f配合使用\-f:依据\-d的分隔字符将信息分割为数段,取出指定的段\-c:以字符为单位,取出固定的字符区间
示例:
1 | # 示例1:从PATH变量中取出第5个路径 |
注意:cut 在处理多空格相连的数据时会比较吃力,这种场景可以考虑使用 awk 来处理。
grep
grep 是分析一行信息,如果当中有我们需要的信息,就将该行拿出来,是非常常用的文本查找工具。
语法格式:
grep \[\-acinv\] \[\-\-color=auto\] \&\#39;搜索字符串\&\#39; filename
参数说明:
\-a:将 binary 文件以 text 文件的方式搜索数据\-c:计算找到搜索字符串的次数\-i:忽略大小写的差异\-n:顺便输出行号\-v:反向选择,即显示出没有搜索字符串内容的那一行\-\-color=auto:将找到的关键字部分加上颜色显示
示例:
1 | # 示例1:从last输出中找出包含root的行 |
二、排序命令:sort、wc、uniq
这类命令可以帮我们对数据进行排序、去重和统计,非常适合用来做数据汇总。
sort
sort 可以帮我们进行排序,支持不同的数据类型排序,比如数字和文字的排序规则是不同的。
语法格式:
sort \[\-fbMnrtuk\] \[file or stdin\]
参数说明:
\-f:忽略大小写的差异\-b:忽略最前面的空白字符部分\-M:以月份的名字来排序\-n:使用纯数字进行排序(默认是以文字形态来排序)\-r:反向排序\-u:相当于 uniq,相同的数据中,仅出现一行代表\-t:分隔符号,默认是用 tab 键来分隔\-k:以指定的区间来进行排序
示例:
1 | # 对/etc/passwd的账号进行默认排序 |
uniq
如果排序完成后,想要将重复的数据仅列出一个,就可以使用 uniq,这个命令会删除重复的行。
语法格式:
uniq \[\-ic\]
参数说明:
\-i:忽略大小写字符的不同\-c:进行计数
注意:uniq 只能去掉相邻的重复行,所以使用前需要先对数据进行排序!
示例:
1 | # 示例1:统计每个用户的登录次数 |
wc
wc 可以帮我们统计文件的整体信息,比如行数、字数、字符数。
语法格式:
wc \[\-lwm\]
参数说明:
\-l:仅列出行\-w:仅列出多少字(英文单字)\-m:多少字符
示例:
1 | # 示例1:统计/etc/man_db.conf的行数、字数、字符数 |
三、双重重定向:tee
我们知道 \> 重定向会将数据全部写入文件,屏幕上就看不到输出了。而 tee 可以实现双向重定向,它会同时将数据流传送到文件和屏幕,这样既可以保存结果,又可以在屏幕上看到输出,方便后续的管线处理。
语法格式:
tee \[\-a\] file
参数说明:
\-a:以累加的方式,将数据加入文件当中,默认是覆盖
示例:
1 | # 示例1:将last的输出保存到文件,同时继续处理输出 |
四、字符转换命令:tr、col、join、paste、expand
这类命令可以帮我们对字符、文本格式进行转换和合并,处理各种格式的文本数据。
tr
tr 可以用来转换字符,比如大小写转换、删除字符等。
语法格式:
tr \[\-ds\] SET1 \.\.\.
参数说明:
\-d:删除信息当中的指定字符串\-s:取代掉重复的字符
示例:
1 | # 示例1:将last的输出全部转成大写 |
col
col 可以用来将 tab 键转换成对应的空白键,让文本显示更整齐。
语法格式:
col \[\-xb\]
参数说明:
\-x:将 tab 键转换成对等的空白键
示例:
1 | # 将文件中的tab转换成空格,方便查看 |
join
join 是用来处理两个文件之间的数据,它会将两个文件中,有相同数据的那一行合并在一起,非常适合用来关联两个相关的文件。
语法格式:
join \[\-ti12\] file1 file2
参数说明:
\-t:默认以空白字符分隔数据,比对第一个字段的数据,如果相同就将两行合并\-i:忽略大小写的差异\-1:代表第一个文件要用哪个字段来分析\-2:代表第二个文件要用哪个字段来分析
注意:使用 join 之前,需要先对处理的文件进行排序,否则有些比对的项目会被略过!
示例:
1 | # 示例1:合并passwd和shadow文件,按账号关联 |
paste
paste 比 join 简单很多,它不需要比对数据,直接将两个文件的行按顺序贴在一起,中间用 tab 分隔。
语法格式:
paste \[\-d\] file1 file2
参数说明:
\-d:后面可以接分隔字符,默认是以 tab 来分隔\-:如果 file 部分写成\-,表示来自 standard input 的数据
示例:
1 | # 示例1:直接将passwd和shadow的行贴在一起 |
expand
expand 专门用来将 tab 键转换成空白键,还可以自定义 tab 对应的空白字符数量。
语法格式:
expand \[\-t\] file
参数说明:
\-t:后面可以接数字,定义一个 tab 按键代表多少个字符,默认是 8 个
示例:
1 | # 示例:将配置文件中的tab转换成6个空格 |
五、划分命令:split
如果你有大文件想要拆分成小文件,比如要拷贝到 U 盘或者发送邮件,split 就可以帮你把大文件按大小或者行数分割成多个小文件。
语法格式:
split \[\-bl\] file PREFIX
参数说明:
\-b:后面可接欲分割成的文件大小,可加单位,例如 b, k, m 等\-l:以行数来进行分割PREFIX:代表分割后文件的前置字符,作为分割文件的前导文字
示例:
1 | # 示例1:将services文件按300K分割 |
六、参数代换:xargs
很多命令其实并不支持管线命令,无法直接接收前一个命令的输出作为参数,这时候 xargs 就可以派上用场了。它可以读入 stdin 的数据,将其分隔成参数,传递给后面的命令。
语法格式:
xargs \[\-0epn\] command
参数说明:
\-0:如果输入的 stdin 含有特殊字符,这个参数可以将它们还原成一般字符\-e:EOF 的意思,后面接一个字符串,当 xargs 分析到这个字符串时,就会停止继续工作\-p:在执行每个命令的 argument 时,都会询问使用者的意思\-n:后面接次数,每次 command 命令执行时,要使用几个参数
示例:
1 | # 示例1:对前3个账号执行id命令,每次处理一个参数 |