首先放出Google的shell编码规范
http://zh-google-styleguide.readthedocs.io/en/latest/google-shell-styleguide/contents/

debug

trap

EXIT 从一个函数中退出或整个脚本执行完毕
ERR 当一条命令返回非零状态时(代表命令执行不成功)
DEBUG 脚本中每一条命令执行之前

tee

tee命令会从标准输入读取数据,将其内容输出到标准输出设备,同时又可将内容保存成文件。例如有如下的脚本片段,其作用是获取本机的ip地址:

set

-o
执行set -o会输出当前的set选项配置情况:

执行set +o也是输出当前的set选项的配置情况,只不过输出形式是一系列的set命令。这种输出形式一般用于重建当前的set配置项时使用。

-e or -o errexit
设置了这个选项后,当一个命令执行失败时,shell会立即退出。

-n or -o noexec
设置了这个选项后,shell读取命令,但是不会执行它们。这个选项可以用来检查shell脚本是否存在语法错误。

-u or -o unset
设置了这个选项之后,当shell要扩展一个还未设置过值的变量时,shell必须输出信息到stderr,然后立即退出。但是交互式shell不应该退出。

-x or -o xtrace
设置了这个选项之后,对于每一条要执行的命令,shell在扩展了命令之后(参数扩展)、执行命令之前,输出trace到stderr。

-o pipefail
这个选项会影响管道的返回值。默认情况下,一个管道的返回值是最后一个命令的返回值,比如cmda | cmdb | cmdc这个管道,返回值是由cmdc命令的返回值决定的。如果指定了pipefail选项,那么管道的返回值就会由最后一个失败的命令决定,意思就是有命令失败就会返回非0值。如果所有命令都成功,则返回成功。

s表示替换命令,/my/表示匹配my,/Hao Chen’s/表示把匹配替换成Hao Chen’s,/g 表示一行上的替换所有的匹配)
-i 参数直接修改文件内容

sed,awk,cut相关

sed

替换字符串
如果
sed “s/my/Hao Chen’s/g” pets.txt

行首添加文字
sed ‘s/^/#/g’ pets.txt

行尾添加
sed ‘s/$/ — /g’ pets.txt

1
2
3
4
5
6
7
^ 表示一行的开头。如:/^#/#开头的匹配。
$ 表示一行的结尾。如:/}$/ 以}结尾的匹配。
\< 表示词首。 如:\<abc 表示以 abc 为首的詞。
\> 表示词尾。 如:abc\> 表示以 abc 結尾的詞。
. 表示任何单个字符。
* 表示某个字符出现了0次或多次。
[ ] 字符集合。 如:[abc] 表示匹配a或b或c,还有 [a-zA-Z] 表示匹配所有的26个字符。如果其中有^表示反,如 [^a] 表示非a的字符

删除某一行
sed -i -e ‘39d’

awk

输出第2列
awk ‘NR==2{print}’

1
2
3
4
5
6
7
8
9
10
$0 当前记录(这个变量中存放着整个行的内容)
$1~$n 当前记录的第n个字段,字段间由FS分隔
FS 输入字段分隔符 默认是空格或Tab
NF 当前记录中的字段个数,就是有多少列
NR 已经读出的记录数,就是行号,从1开始,如果有多个文件话,这个值也是不断累加中。
FNR 当前记录数,与NR不同的是,这个值会是各个文件自己的行号
RS 输入的记录分隔符, 默认为换行符
OFS 输出字段分隔符, 默认也是空格
ORS 输出的记录分隔符,默认为换行符
FILENAME 当前输入文件的名字

cut

cut 的工作就是”剪”,就是在文件中负责裁剪数据;cut 是以每一行为一个处理对象的;
cut 一般以什么为依据呢?也就是说,我怎么告诉 cut 我想定位到的剪切内容呢?三种方式:

字节 byte:选项 -b
字符 char:选项 -c
字段 field:选项 -f

1
2
3
4
5
6
7
8
9
10
11
### 字节
echo 'abcdefg' | cut -b 2 # 获取第二个字节;"b"
echo 'abcdefg' | cut -b 2,4-6 # 获取第二个字节和第 4-6 个字节,类似用法下同;"bdef"
echo 'abcdefg' | cut -b -3 # 获取开头至第三个字节,即前三个字节,类似用法下同;"abc"
echo 'abcdefg' | cut -b 3- # 获取第三个字节至行尾,类似用法下同;"cdefg"
### 字符
echo 'abcdefg' | cut -c 2 # "b"
### 字段
head -5 /etc/passwd | cut -d':' -f1 # -d 指定分割符,-f 指定字段号

tr

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
tr 即 translate,翻译、转换;tr 只处理标准输入,如果需要处理文件请使用重定向;
tr [OPTION]... SET1 [SET2]
### 常用参数
# -c, -C, --complement 使用 SET1 的补码(即不在集合中的字符)
# -d, --delete 删除 SET1 中的字符
# -s, --squeeze-repeats 合并连续的重复字符,在合并多个空格时很有用,此时 SET2 无效
#
# SET 集合:
# \\ 反斜杠
# \a 响铃
# \b 退格
# \r 回车
# \n 换行
# \f 换页
# \t 水平制表
# \v 垂直制表
# \NNN 八进制数字(1~3 位)
# CHAR1-CHAR2 字符/数字范围
# [:alpha:] 字母
# [:digit:] 数字
# [:alnum:] 字母 + 数字
# [:lower:] 小写字母
# [:upper:] 大写字母
# [:cntrl:] 控制符
# [:print:] 可打印字符,包括空格
# [:graph:] 可显示字符,不包括空格
# [:punct:] 标点符号
# [:blank:] 空白符
# [:space:] 水平或垂直空白
# [:xdigit:] 十六进制数字

命令举例

tr ‘a-z’ ‘A-Z’ < test.txt # 大小写转换
tr ‘ ‘ ‘\t’ < test.txt # 空格转换为 tab
tr -s ‘ ‘ ‘ ‘ < test.txt # 合并连续空格
tr -d ‘ ‘ < test.txt # 删除所有空格

https://www.ibm.com/developerworks/cn/linux/l-cn-shell-debug/index.html
https://coolshell.cn/articles/9104.html
https://segmentfault.com/a/1190000003005706