Shell 中的文本处理【简】

0X00 前言

在这里介绍 Shell 脚本编程和日常的命令行操作中最常用的 9 个命令,希望对读到这篇文章的你有所帮助~

这是一篇基础得不能再基础的内容,如果你看完还能有两三个收获的话,那就一起来恶补 Linux 知识吧🤣

0X01 cat

cat 命令应该是学习 Linux 命令时候最早接触到的命令之一了,自然不用多说什么,这里只提一个用法:如何 cat 命令创建一个文件。例如在脚本中我们需要创建一个配置文件,当然可以把配置文件跟脚本文件放一起,然后 cp 过去,但是如果你想用一个文件搞定的话(这样在看脚本的时候就知道配置文件是什么内容了,看着舒服改起来也方便)就可以这么操作

1
2
3
4
5
cat << EOF > xxx.conf
[main]
var = 123
var = 123
EOF

这段命令写在 shell 脚本中就意味着会把两个 EOF 中间行的内容作为文件 cat 一下,再接上后面的重定向,就把它写入到 xxx.conf 中了。不仅可以在脚本中,直接写在命令行中也是可以的。当然也可以不带重定向使用。

这里有一篇阮一峰的文章在相对详细的介绍什么是 EOF。

需要注意的是 EOF 只是我们约定俗成的 Enf Of File 的缩写,你非要用别的表示也是可以的(比如你的文本中包含 EOF 的话就有必要改用别的)

0X02 echo

echo 命令用起来比 cat 还要更简单,只需要介绍三个简单的参数

  • echo -n 不输出尾部换行符
  • echo -e 启用反斜杠转义
  • echo -E 禁用反斜杠转义(Debian 默认是禁用的)

0X03 printf

printf 是一个类似于 echo 但是比 echo 用法更细致的命令,非常类似于 C 里面的 printf

1
2
3
4
5
printf "hello, world\n" # 会有转义
printf "%-10s" xxxxx # 会输出内容并且长度不足 10 的用空格填充,左对齐
printf "%10s" yyy # 同上,右对齐
printf "%-4.2f" 12.345 # 与 C 的用法一致
printf "%4d" 12 # 与 C 的用法一致

0X04 head/tail

head/tail 这两个命令最主要的用法就是 -n 参数,例如看某个文件的前 10 行可以用 head filename -n 10,末尾 3 行就是 tail filename -n 3,串起来也可以用 cat xxx file | head -n 30 | tail -n 10 就看到这个文件的 21 到 30 行了。

其中 tail 命令还有一个常用的参数是 -f,它意味着当读到文件末尾的时候不会停止,而是继续等待新内容。例如有一个源源不断产生新内容的日志文件 operation.log,我们可以 tail -f operation.log 来监控它,每当有新内容写进去的时候都会第一时间输出出来。

另外 tail -f 还可以同时监控多个文件,例如 tail -f aaa.log bbb.log ccc.log,不仅会实时监控文件中追加的新内容,还会用类似下面这种的方式区分开来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
❯ tail -f aaa bbb ccc
==> aaa <==

==> bbb <==

==> ccc <==

==> aaa <==
aaa
aaa
aaa

==> bbb <==
bbb
bbb

0X05 wc

wc 命令的是用来计数的,可以以 bytes/chars/lines/words 来统计。例如 wc -l filename 就是检查这个文本文件总共有多少行,wc -c 是多少个字节,-m 是多少个字符……

通常用的最多的就是数行数了

0X06 grep

关于 grep 是没办法在这里讲清楚的,只能简单介绍几个基本用法,这里挖个坑,后面争取写一个关于 Linux 文本三剑客的文章介绍一下它们的用法。

grep 是从文本中查找子字符串的命令,最常用的用法就是 cat filename | grep xxxx 这种查找文件中内容的用法了,这里简单介绍几个常用的用法

  • grep xxx -A 3 其中的 -A 3 就是 after 3 line 的意思,也就是说顺带输出找到的内容的后面三行
  • grep xxx -B 3 同理,就是 before 3 line
  • grep xxx -C 3 同理,哦不对没法同理。这里的 -C 有点像是玩梗,既然 AB 都有了那顺便也搞了个 C,这里的 -C 3 意思和 -A 3 -B 3 相同,意味着同时输出前后三行
  • grep -Rn xxx . 从当前路径递归查找含有 xxx 的行,并且同时输出该行所在的文件和行号(通常在代码库中查找代码会用到)

https://grep.js.org/ 是一个在线 grep 工具,方便你练习 grep 命令

0X07 awk

同上,awk也是所谓文本三剑客中的一员,这里只是简单介绍一下最基础的用法

awk 是将一个文本内容逐行拆分的命令,ls -l 可以看到文件的详细信息,用 awk 可以=将其中的某一列提取出来,例如提取文件所属人 ls -l | awk -F ' ' '{print $3}' 就可以了。其中 awk 命令的参数分成两部分,前半部分是 -F ' ' 意味着我要指定一个分隔符,这个分隔符是空格;后半段是 {print $3} 意味着我要打印出第三段来(也就是文件所属人的这一列)

https://awk.js.org/ 是一个在线 awk 工具,方便你练习 awk 命令

0X08 sed

继续同上,sed也是三剑客中的一员,这里简单介绍

sed 是一个修改文本内容的命令,具体的修改方法跟 vim 的替换内容很像,下面列举几个常常见的用法

  • sed "s/hello/world/g" filename 将这个文件中的 hello 替换为 world 并打印出来(不修改)
  • sed -i "s/hello/world/g" filename 只是多了个 -i 参数,从打印不修改原文变成了修改原文但不打印
  • sed -i "s/hello/world/" filename 去掉了 g 就是每行只替换一处

https://sed.js.org/ 是一个在线 sed 工具,方便你练习 sed 命令

grep 是 1973 被开发出来的, sed 是 1974, awk 是 1977,这也是为什么如今大家还会推荐新人学习命令行工具,因为这些命令行工具学一次真的能用一生

0X09 xargs

关于 xargs 我也打算单独写一个文章来介绍。哦不对,不用打算,我已经写了🥹

0X10 最后

Linux 下每个命令都有很多参数,即使是 head 这种看起来很简单的命令都有 5 个参数,tail 就更多了,后面的 grep/awk/sed 三剑客几乎都是可以单独写本书的水平。所以建议没事的时候可以看看 man 的文档,不一定要记住都有哪些参数具体怎么用,但是多看一看就会对其中一些用法有印象,下次再用到的时候起码知道哪个命令能用。具体怎么用再来看文档就好了~