2019-08-27

shell-Startup-Files

shell-Startup-Files

1. 相关阅读
2. 主流shell
3. shell实例类型
4. Shell启动文件的必要元素
 4.1 路径: 命令路径, 
 4.2 提示符
5. 主流shell的配置文件
6. 默认的bash
 6.1 手册
 6.2 bash启动文件
 6.3 提示符
7. 友好的fish
 7.1 简介
 7.2 查看帮助文档
 7.3 fish的配置
8. zsh

1. 相关阅读


https://www.cnblogs.com/sztom/p/11349159.html
shell脚本

https://szosoft.blogspot.com/2019/07/console-terminal-tty-shell-kernel.html
https://www.cnblogs.com/sztom/p/11247883.html
Console-terminal-tty-shell-kernel
Shell在计算机系统中的位置

http://hyperpolyglot.org/unix-shells
常用shell语法对照(Unix Shells: Bash, Fish, Ksh, Tcsh, Zsh)

https://en.wikipedia.org/wiki/Comparison_of_command_shells

https://opensource.com/business/16/3/top-linux-shells
Linux的前5个开源命令shell

https://www.ibm.com/developerworks/cn/aix/library/au-spunix_fish/index.html
Friendly Interactive Shell(fish)对于 UNIX 新手和专家都很适合

https://wiki.archlinux.org/index.php/Command-line_shell
https://wiki.archlinux.org/index.php/Command-line_shell#POSIX_compliant
https://wiki.archlinux.org/index.php/Command-line_shell#Alternative_shells

https://en.wikipedia.org/wiki/Unix_shell
https://en.wikipedia.org/wiki/Unix_shell#Configuration_files

https://wiki.gentoo.org/wiki/Shell
https://wiki.gentoo.org/wiki/Shell#Available_software

https://en.wikibooks.org/wiki/Bash_Shell_Scripting

https://developer.ibm.com/tutorials/l-linux-shells/


2. 主流shell

Name Description POSIX License user
bash
(默认)
The Bourne Again Shell, is the default shell on Gentoo. It is used by Portage, Gentoo's default package manager. 符合 compliant GPLv3 54%
fish
(友好)
The Friendly Interactive Shell. (2005) Alternative 替代 GPLv2… 12%
zsh
(极客)
An advanced shell that is the chosen interactive shell for many users. 符合 compliant MIT, GPL 23%
tcsh an enhanced version of the Berkeley C Shell (csh). Alternative 替代 BSD 3%
ksh The Original Korn Shell, 1993 revision (ksh93). 符合 compliant Eclipse Public 3%
Other


5%


https://developer.ibm.com/tutorials/l-linux-shells/#unix-shells-since-1977
https://developer.ibm.com/developer/tutorials/l-linux-shells/images/figure1.gif

3. shell实例类型


大类 小类 系统配置文件 用户配置文件
交互式 登录shell (初始shell) /etc/profile .bash_profile;
.bash_login;
.profile …
交互式 非登录shell /etc/bash.bashrc .bashrc
非交互式 运行shell脚本的shell等 通常不读取启动文件

4. Shell启动文件的必要元素

路径,提示符,别名alias,权限掩码(077;022)

4.1 路径: 命令路径,

/usr/local/bin
/usr/bin
/bin
这个顺序可以确保/usr/local中的特定变体覆盖默认程序。
大多数Linux发行版中,几乎所有软件包都会被安装到/usr/bin中。也有少数情况(游戏: /usr/games; 图形应用还有另外的地方)
可以将一些分散程序的符号链接放到/usr/local/bin中。

若对系统工具感兴趣(traceroute,ping,lsmod...),可以为路径加上sbin目录。
/usr/local/sbin
/usr/sbin
/sbin

帮助手册的路径: 建议不要修改。
传统的帮助手册路径来自环境变量MANPATH. /etc/manpath.config

4.2 提示符

PS1='[\u@\h \w]\n\A \!-\#\$ '


5. 主流shell的配置文件


files bash sh ksh zsh tcsh
/etc/.login



login
/etc/csh.login



login
~/.login



login
~/.logout



login
/etc/csh.cshrc



yes
~/.tcshrc ; ~/.cshrc



yes[a]
~/etc/ksh.kshrc

int.

/etc/sh.shrc
int.[b]


$ENV (typically ~/.kshrc) int.[e] int.[c][d] int.

~/.bashrc int.+n/login



~/.bash_profile login[g]



~/.bash_login login[g]



~/.bash_logout login



~/.profile login[g] login login login[f]
/etc/profile login login login login[f]
/etc/zshenv


yes
/etc/zprofile


login
/etc/zlogin


login
/etc/zlogout


login
/etc/zshrc


int.
~/.zshenv


yes
~/.zprofile


login
~/.zlogin


login
~/.zshrc


int.


n/login 表示如果shell不是登录shell,则读取文件。
login 表示如果shell是登录shell,则读取文件。
int. 表示如果shell是交互式的,则读取文件。
yes 表示shell在启动时始终读取文件。
" " 空白表示shell根本不读取文件。


[a] 仅在找不到~/.tcshrc时
[b] 仅限Bourne Shell的较新版本
[c] 适用于支持"用户可移植性实用程序"选项的系统; 变量的值必须是绝对路径,如果用户的真实有效用户ID或真实有效的组ID不同,则忽略它。
[d] $ENV是在Bourne Shell中的较新版本$HOME/.shrc
[e] 与 sh相同的行为,但仅在调用为 sh(bash 2+)或者自bash 4.2时,如果在POSIX兼容模式中显式调用(使用选项 --posix或 -o posix).
[f] a,b仅在sh/ksh兼容模式下(当调用为bash,sh,ksh时)
[g] 实际上是b,c,~/ .bash_profile的第一个可读,~/ .bash_login和~/ .profile ; 并且只有~/ .profile如果被调用为sh或者,至少在Bash 4.2中,如果在POSIX兼容模式中显式调用(带有选项--posix或-o posix)

6. 默认的bash

Bash主页是 http://www.gnu.org/software/bash/
https://wiki.archlinux.org/index.php/Bash
https://wiki.archlinux.org/index.php/Bash#Configuration_files

https://wiki.gentoo.org/wiki/Bash

6.1 手册

https://www.gnu.org/software/bash/manual/bash.html
file:///usr/share/doc/bash/bashref.html

6.2 bash启动文件

https://www.gnu.org/software/bash/manual/bash.html#Bash-Startup-Files

文件 描述 登录shell 交互,
非登录shell
/etc/profile 来源在应用程序设置/etc/profile.d/*.sh和/etc/bash.bashrc。 Yes No
~/.bash_profile 用户,之后/etc/profile。如果这个文件不存在,~/.bash_login并~/.profile按照此顺序检查。骨架文件/etc/skel/.bash_profile也来源~/.bashrc。 Yes No
~/.bash_logout 退出登录shell后。 Yes No
/etc/bash.bashrc 取决于-DSYS_BASHRC="/etc/bash.bashrc"编译标志。来源/usr/share/bash-completion/bash_completion。 No Yes
~/.bashrc 每用户,之后/etc/bash.bashrc。 No Yes

https://zhuanlan.zhihu.com/p/33833752
如何列出所有的 Bash Shell 内置命令


6.3 提示符

PS1='[\u@\h \w]\n\A \!-\#\$ '

PS1='\e[0;36m\][\u@\h \w]\e[0m\] \e[0;32m\]\n\A \!-\#\$\e[0m\] '
PS1='\e[0;36m\][\u@\h \w] \e[0;32m\]\n\A \!-\#\$\e[0m\] '

Code Color
\e[0;30m\] Black
\e[0;31m\] Red
\e[0;32m\] Green
\e[0;33m\] Yellow
\e[0;34m\] Blue
\e[0;35m\] Magenta 品红
\e[0;36m\] Cyan 青色
\e[0;37m\] White
\e[0m\] Reset to standard colors 重置为标准色

7. 友好的fish

7.1 简介

https://en.wikipedia.org/wiki/Friendly_interactive_shell
https://zh.wikipedia.org/wiki/Fish
fish的设计目标是以易于发现,记忆和使用的方式为用户提供丰富的强大功能。
它的语法既不来自Bourne shell(ksh,bash,zsh)也不是C shell(csh,tcsh)。
与以前的shell(默认情况下禁用某些功能以节省系统资源)不同,fish默认启用所有功能。

https://wiki.archlinux.org/index.php/Fish
https://wiki.archlinux.org/index.php/Fish_(简体中文)
fish被有意设计成不完全与POSIX兼容。
fish的作者们认为POSIX中存在一些缺陷和矛盾,并通过fish简化的或不同的语法解决这些问题。
因此,即使简单的POSIX兼容的脚本也可能需要较多的修改,甚至完全重写,才能在fish中运行。
https://wiki.archlinux.org/index.php/Fish#Setting_fish_as_interactive_shell_only
只把fish设为交互式shell

https://wiki.gentoo.org/wiki/Fish
fish是OS X,Linux和其他家族的智能且用户友好的命令行shell。
fish包含语法突出显示,自动提示类型和精美的选项卡完成等功能,无需配置。
Fish不是POSIX 1003.1兼容的shell。它不读取/etc/profile,/etc/profile.env或/etc/profile.d/*目录。
建议不要将fish设置为默认登录shell.
这里有其中一位鱼类开发者和Arch wiki建议的技巧。这使得fish shell能够继承bash环境(写入并应该由bash shell 执行)
详见: https://wiki.gentoo.org/wiki/Fish#.bashrc_safety_net

https://github.com/fish-shell/fish-shell

7.2 查看帮助文档

$ help
file:///usr/share/doc/fish/index.html#docs
与其他shell不同,这里直接打开web页面文档,更方便查看,还能使用网页翻译。与下方官网页面相同。
https://fishshell.com/docs/current/index.html

官网的教学及常见问题
https://fishshell.com/docs/current/tutorial.html
https://fishshell.com/docs/current/faq.html

7.3 fish的配置

$ fish_config
Web config started at 'file:///home/toma/.cache/fish/web_config-S2EKS6.html'. Hit enter to stop.
不需要编写脚本,不需要手动修改配置文件,使用 fish_config 命令打开网页即可。
比如: http://localhost:8000/6d9de3bf1bf313e974c9738471da505c/#/colors
  • colors 配色模式 (我选择了省电的黑色背景,彩色文字模式)
  • prompt 提示符号 (我选择了完整路径显示加时间,加换行模式)
  • functions 功能
  • variables 变量
  • history 历史 (这里可以看到所有已经使用过的历史命令,可以手动删除不需要的命令)
  • bindings 绑定
  • abbreviations 缩写

8. zsh

这个可以吧shell玩的很酷炫,有非常多的插件可以选择。
也要话时间适应研究,这里就直接跳过了。
网络上有非常多的相关文章可共参考。

2019-08-13

linux-shell


1. shell脚本文件
2. shell脚本的局限性
3. shell脚本执行说明
4. 引号与字面量
   4.1 单引号的字面义
   4.2 双引号内可以使用单引号。
   4.3 倒引号(左上角Tab键上面那个键)
5. 特殊变量
   5.1 能删除第一个参数的shift命令
   5.2 特殊符号
   5.3 退出码
6. 条件判断
   6.1 使用其他命令来测试,grep
   6.2 多条件分支 elif
   6.3 多条件分支 case
   6.4 逻辑结构: &&(和); ||(或)
   6.5 测试条件
   6.6 test运算符可分为三类 man test(1)
      6.6.1 一元运算符,之要求一个参数,比如前面的-f
      6.6.2 二元运算符
      6.6.3 字符串测试
      6.6.4 算术测试
      6.6.5 case字符串匹配
7. for循环
8. while循环
9. 命令替换
10. 管理临时文件
11. here文档
12. 重要的shell脚本工具
   12.1 去掉扩展名
   12.2 grep,awk,sed等模式查找,分析,编辑工具
   12.3 xargs
   12.4 expr
   12.5 exec 命令是shell内置的,他会用其后的程序的进程来取代当前的shell进程。
   12.6 子shell
   12.7 在脚本中包含其他文件(.)
   12.8 读取用户输入read
13. shell例子
14. 部分工具帮助
   14.1 xargs
   14.2 expr
15. 更多学习相关链接

shell脚本笔记
Bourne shell脚本,就是将一系列命令写在一个文件当中,然后让shell从该文件读取命令,就像从终端读取一样。

1. shell脚本文件


  1. 使用.sh作为后缀的脚本文件,很多文本编辑器默认显示为彩色编码模式。
  2. #!/bin/sh # 指定脚本解释器,这里是用/bin/sh做解释器的
  3. # 注释符号。
  4. 运行方式1: (直接运行) $ bash sh02.sh 或者 $ sh sh02.sh
  5. 运行方式2: (作为可执行文件)可执行权限: chmod +rx test.sh, 或者 chmod 700 test.sh 等给脚本执行和读取(5 or 7)的权限。然后运行脚本 $ ./test.sh


2. shell脚本的局限性

shell脚本的优点是能使任务简单化,自动化,而不用在命令行提示符下一条条的敲命令。对于批量处理文件很方便。特别适合处理一些系统管理方面的小问题.类似Windows的批处理文件(*.bat)

但是如果哦要分解字符串,做繁复的数学计算,复杂的数据库交互,或者想写函数及复杂的控制结构,最好使用Python, Perl之类的脚本语言,或者awk,甚至C这样的编译型语言。

3. shell脚本执行说明

在执行之前,shell会查找其中的变量,通配符以及其他代词,如果有的话,就将他们进行替代。
将替换后的结果返回给命令。

4. 引号与字面量

引号通常用于创建字面量,即原封不动的字面义。
单引号保证shell不会做任何替换。如下面的单引号。
echo $100
$ ./sh01
00
$ ./sh01 hh
hh00
echo "$100"
$ ./sh01
00
echo '$100'
$ ./sh01
$100
 echo 'There is no * in mp path: $PATH'
There is no * in mp path: $PATH
双引号与单引号差不多,只是shell会对双引号中所有变量都进行扩展。如下面的双引号,$PATH会被替换,*号不变。
$ echo "There is no * in mp path: $PATH"
There is no * in mp path: /usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl

4.1 单引号的字面义

 echo I don\'t like.
I don't like.
反斜和单引号不能被任何单引号对包裹。
$ echo 'I don\'t like.' //错误语法

4.2 双引号内可以使用单引号。

echo "I don't like."
I don't like.
'不做转换'的一般做法:
1. 将所有'(单引号)改成'\''(单引号,反斜,单引号,单引号);
2. 用单引号对'包裹整个'字符串.
 echo 'I don'\''t like.'
I don't like.

4.3 倒引号(左上角Tab键上面那个键)

由倒引号括起来的字符串被shell解释为命令行,在执行时,shell会先执行该命令,并以他的标准输出结果取代整个引号部分。

5. 特殊变量

单个参数: $1, $2, ...
正整数命名的变量,都包含了脚本的参数值。
比如脚本文件 sh01:
#!/bin/sh
echo First argument: $1
echo First argument: $3
$ sudo chmod 755 sh01
$ ./sh01 01 02 03
First argument: 01
First argument: 03

5.1 能删除第一个参数的shift命令

脚本文件sh01的内容 执行sh01脚本
比如: a001

5.2 特殊符号

单个参数: $1, $2, ...
删除第一个参数的命令: shift
参数的数量: $#
所有参数: $@
分割长行用反斜: \
脚本名: $0

标准错误重定向到标准输出: 2>&1
标准输出重定向到标准错误: 1>&2

5.3 退出码

进程号: $$
退出码: $?
$ echo $?
0
通常0表示正常退出.
$ ls /psddsdf
ls: cannot access '/psddsdf': No such file or directory
$ echo $?
2
$ echo $?
0
通常非0表示非正常退出。如上例的2。
连续使用2次echo $?, 第二次总是正常退出0.
指定退出码: exit 1
特例,diff,grep正常退出时也会用到非0码。
grep会在匹配时返回0, 不匹配时返回1.
grep和diff使用2来代表出错。
特别的退出码信息可以在命令的帮助信息里查询,通常在EXIT VALUE或DIAGNOSTICS小节中。

6. 条件判断

if/then/ else和case语句
比如: a003

'['字符是Unix系统中一个实际存在的命令,而不是shell的语法。他能进行条件测试,也叫test。
对比'['和'test',会发现他们指向同一个inode。或者其中一个是另一个的符号链接。

条件判断的执行说明
条件判断开始与if;
shell执行if关键字后的命令,获取其推出码;
如果退出码是0,shell就会接着执行then关键字后的命令;直至遇到else或fi关键字;
如果退出码非0,并且有else,就会执行else后面的命令;
条件判断至与fi。

防范空参数
if [ "$1" = hi ]; then
if [ x"$1" = x"hi" ]; then

if后面必须是命令,如果想将then放在同一行,必须在test命令后面加上分号(;).如果没有分号,text命令会将then当成参数。
不想用分号,可以换行输入then。

6.1 使用其他命令来测试,grep

比如: a005

6.2 多条件分支 elif

比如: a007

6.3 多条件分支 case


6.4 逻辑结构: &&(和); ||(或)

cmd1 && cmd2
执行cmd1到退出码为0,接着执行cmd2.
cmd1 || cmd2
执行cmd1到退出码为非0,接着执行cmd2.

if cmd1 && cmd2
若执行cmd1到退出码为0,会接着执行cmd2. if取cmd2的退出码作为判断结果;
若执行cmd1到退出码为非0,if直接取这个非0值作为判断结果;不需要在执行cmd2.
if cmd1 || cmd2
若执行cmd1到退出码为0,if直接取这个0值作为判断结果;不需要在执行cmd2.
执行cmd1到退出码为0,会接着执行cmd2. if取cmd2的退出码作为判断结果;

如果条件判断包含了text([)命令,可以使用-a, -o代替&&, ||.

6.5 测试条件

比如: a009

6.6 test运算符可分为三类 man test(1)

文件测试
字符串测试
算术测试

6.6.1 一元运算符,之要求一个参数,比如前面的-f

-e: 文件存在时返回 true
-s: 文件非空时返回 true
文件类型运算符
-f: 普通文件
-d: 目录
-h: 符号链接
-b: 块设备
-c: 字符设备
-p: 命名管道
-s: 套接字

test命令会直达符号链接所指的文件(除非用-h测试)。
即,如果哦link是某个普通文件的符号链接,则[-f link]返回true (退出码为0)

文件权限运算符
-r: 可读
-w: 可写
-x: 可执行
-u: Setuid
-g: Setgid
-k: "Sticky"

6.6.2 二元运算符

-nt: a新于b 返回true
-ot: a旧与b 返回true
-ef: a是否是b的硬链接

6.6.3 字符串测试

=:  2个字符串相同 返回true
!=: 2个字符串不同 返回true
-z: 参数为空 返回true
-n: 参数非空 返回true

6.6.4 算术测试

=: 测试字符串的,不是数字!
-eq: 相等
-ne: 不等
-lt: 更小
-gt: 更大
-le: 更小或相等
-ge: 更大或相等

6.6.5 case字符串匹配

case条件判断不执行任何test命令,因此没有退出码。它是做模式匹配的。
a011
遇到匹配的就会运行后面的命令,直到;;时,跳到esac关键字。

7. for循环

比如: a013

8. while循环

会用到退出码,非0就退出。
比如: a015

进行grep -q firstline测试。只要该测试的退出码非0(本例中,若$FILE的最后10行不包含字符串firstline,则非0),循环就会结束。

可以用break语句打断while循环。
还有类似的until循环,退出码为0.
建议:应该用awk或Python来代替while。

9. 命令替换

用$()将命令包围,使该命令的输出被当作变量来使用。
比如: a017
grep的结果发送到sed;
sed将匹配.*:的内容清空掉,再发送给head;

不要过度使用命令替换
比如在脚本中不要使用$(ls), 而是改用shell展开*, 因为这样更快捷。

命令替换的传统做法是使用反引号(‘’)包围命令.
$()语法是一种较新的形式,且符合POSIX标准,更容易阅读和编写。

10. 管理临时文件

比如: a019

11. here文档

用于打印大段文字,类似html的<pre>标签。注,here文档中的shell变量都会被展开。
比如: a021

12. 重要的shell脚本工具

basename等很少单独使用,通常出现在脚本里。

12.1 去掉扩展名

$ basename example.html .html

去掉目录部分
$ basename /usr/local/bin/example

gif转换为png
比如: a023

12.2 grep,awk,sed等模式查找,分析,编辑工具


12.3 xargs

从标准输入构建和执行命令行.
本手册页记录了xargs的GNU版本。
xargs从标准输入中读取项目,由空格分隔(可以使用双引号或单引号或反斜杠保护)或换行符,并使用任何初始参数执行命令(默认为/bin/echo)一次或多次从标准输入读取的项目。
标准输入上的空行将被忽略。

构建命令的命令行直到达到系统定义的限制(除非使用-n和-L选项)。
将根据需要多次调用指定的命令以使用输入项列表。
通常,命令的调用次数将少于输入中的项目。
这通常会带来显着的性能优势。
有些命令也可以并行执行;请参阅-P选项。

因为Unix文件名可以包含空格和换行符,所以这种默认行为通常是有问题的;包含空格和/或换行符的文件名由xargs错误处理。
在这些情况下,最好使用-0选项,以防止此类问题。
使用此选项时,您需要确保为xargs生成输入的程序也使用空字符作为分隔符。
例如,如果该程序是GNU find,则-print0选项会为您执行此操作。

如果命令的任何调用以状态255退出,则xargs将立即停止而不读取任何进一步的输入。
发生这种情况时,会在stderr上发出错误消息。

$ xargs --show-limits
您的环境变量占用2600个字节
参数长度的POSIX上限(本系统):2092504
参数长度的POSIX最小允许上限(所有系统):4096
我们实际可以使用的最大命令长度:2089904
我们实际使用的命令缓冲区大小:131072
最大并行度( -  max-procs必须不大):2147483647

xargs的执行现在将继续,它将尝试读取其输入和运行命令; 如果这不是您想要的,请输入文件结束键击。
警告:echo至少运行一次。 如果您不希望发生这种情况,请按中断键。

12.4 expr

计算表达式

12.5 exec 命令是shell内置的,他会用其后的程序的进程来取代当前的shell进程。

此功能的目的是节省系统资源,没有返回值。
当在shell脚本中运行exec时,该脚本及运行该脚本的shell会失踪,而被exec后的命令取代。
可以运行 exec cat 查看效果。当按下 ctrl + C 或 ctrl + D 时,shell窗口就会消失。

12.6 子shell

新开一个进程来运行子shell,新shell复制原shell的环境变量,而在其退出时,在这个新shell下对环境变量的任何更改不会影响到原shell。
将命令置于括号中,即可运行子shell。
#!/bin/sh
echo 'o:$PATH'
echo "Old:$PATH"
(PATH=/home/toma/Desktop:$PATH; echo "New:$PATH")
echo "Old:$PATH"

更快的复制
$ tar cf - orig | (cd target; tar xvf -)
用tar将orig整个目录树打包,并在target目录中解包。高效的复制了orig中的文件和目录。
这种做法保留了权限,且一般会比(cp -r)快。

12.7 在脚本中包含其他文件(.)

. config.sh
包换语法不会开启子shell,且便于在脚本中调用配置文件。

12.8 读取用户输入read

$ read var
将输入至于$var.

13. shell例子

a001 #!/bin/sh
echo First argument: $1
echo First argument: $2
echo First argument: $3
shift
echo First argument: $1
echo First argument: $2
echo First argument: $3
shift
echo First argument: $1
echo First argument: $2
echo First argument: $3
a003 #!/bin/sh
if [ $1 = hi ]; then
echo 'The first argument was "hi"'
else
echo -n 'The first argument was not "hi" -- '
echo It was '"'$1'"'
fi

if [ "$1" = hi ]; then
if [ x"$1" = x"hi" ]; then
a005 #!/bin/sh
if grep -q daemon /etc/passwd; then
echo The daemon user is in the passwd file.
else
echo There is a big problem. daemon is not in the passwd file.
fi

#!/bin/sh
if grep -q $1 /etc/passwd; then
echo The '"'$1'"' user is in the passwd file.
else
echo There is a big problem. '"'$1'"' is not in the passwd file.
fi
a007 #!/bin/sh
if [ "$1" = "hi" ]; then
echo 'The first argument was "hi"'
elif [ "$2" = "bye" ]; then
echo 'The second argument was "bye"'
else
echo -n 'The first argument was not "hi" and the second was not "bye"-- '
echo They were '"'$1'"' and '"'$2'"'
fi
a009 #!/bin/sh
for filename in *; do
if [ -f $filename ]; then
ls -l $filename
file $filename
else
echo $filename is not a regular file.
fi
done
a011 #!/bin/sh
case $1 in
bye)
echo Fine, bye.
;;
hi|hello)
echo Nice to see you.
;;
what*)
echo Whatever.
;;
*)
echo 'Huh?'
;;
esac
a013 #!/bin/sh
for str in one two three; do
echo $str
done
a015 #!/bin/sh
FILE=/tmp/whiletest.$$;
echo firstline> $FILE
while tail -10 $FILE | grep -q firstline;
do
# add lines to $FILE until tail -10 $FILE no longer prints "firstline"
echo -n Number of lines in $FILE:' '
wc -l $FILE | awk '{print $1}'
echo newline ?? $FILE
done

rm -f $FILE
a017 #!/bin/sh
FLAGS=$(grep ^flags /proc/cpuinfo | sed 's/.*://' | head -1)
echo Your processor supports:
for f in $FLAGS; do
case $f in
fpu) MSG="floating point unit"
;;
3dnow) MSG="3DNOW graphics extensions"
;;
mtrr) MSG="memory type range register"
;;
*) MSG="unknown"
;;
esac
echo $f: $MSG
Done
a019 #!/bin/sh
TMPFILE1=$(mktemp /tmp/im1.XXXXXX)
TMPFILE2=$(mktemp /tmp/im2.XXXXXX)
# trap "rm -f $TMPFILE1 $TMPFILE2; exit 1" INT
# --snip--
cat /proc/interrupts > $TMPFILE1
sleep 2
cat /proc/interrupts > $TMPFILE2
diff $TMPFILE1 $TMPFILE2
rm -f $TMPFILE1 $TMPFILE2
a021 #!/bin/sh
DATE=$(date)
UNIXDATE=$(date +%s)

cat <<EOF
Date: $DATE
UNIXDATE: $UNIXDATE
The output above is from the Unix date command.
It's not a very interesting command.
EOF
a023 #!/bin/sh
for file in *.fig; do
# exit if there are no files
if [ ! -f $file ]; then
exit
Fi
b=$(basename $file .gif)
echo Converting $b.gif to $b.png...
giftopnm $b.gif | pnmtopng > $b.png
done

14. 部分工具帮助

14.1 xargs

-0, --null items are separated by a null, not whitespace; disables quote and backslash processing and logical EOF processing items由null而不是空格分隔;禁用报价和反斜杠处理以及逻辑EOF处理
-a, --arg-file=FILE read arguments from FILE, not standard input 从FILE读取参数,而不是标准输入
-d, --delimiter=CHARACTER items in input stream are separated by CHARACTER, not by whitespace; disables quote and backslash processing and logical EOF processing 输入流中的项目由CHARACTER分隔,而不是由空格分隔;禁用报价和反斜杠处理以及逻辑EOF处理
-E END set logical EOF string; if END occurs as a line of input, the rest of the input is ignored (ignored if -0 or -d was specified) 设置逻辑EOF字符串;如果END作为输入行出现,则忽略输入的其余部分(如果指定了-0或-d则忽略)
-e, --eof[=END] equivalent to -E END if END is specified; otherwise, there is no end-of-file string 如果指定了END,则相当于-E END;否则,没有文件结束字符串
-I R same as --replace=R 与--replace = R相同
-i, --replace[=R] replace R in INITIAL-ARGS with names read from standard input; if R is unspecified, assume {} 用INITIAL-ARGS中的R替换从标准输入读取的名称;如果R未指定,则假设{}
-L, --max-lines=MAX-LINES use at most MAX-LINES non-blank input lines per command line 每个命令行最多使用MAX-LINES非空白输入行
-l[MAX-LINES] similar to -L but defaults to at most one nonblank input line if MAX-LINES is not specified 类似于-L,但如果未指定MAX-LINES,则默认为最多一个非空白输入行
-n, --max-args=MAX-ARGS use at most MAX-ARGS arguments per command line 每个命令行最多使用MAX-ARGS参数
-P, --max-procs=MAX-PROCS run at most MAX-PROCS processes at a time 一次运行大多数MAX-PROCS进程
-p, --interactive prompt before running commands 运行命令前提示
--process-slot-var=VAR set environment variable VAR in child processes 在子进程中设置环境变量VAR
-r, --no-run-if-empty if there are no arguments, then do not run COMMAND; if this option is not given, COMMAND will be run at least once 如果没有参数,则不要运行COMMAND;如果未给出此选项,COMMAND将至少运行一次
-s, --max-chars=MAX-CHARS limit length of command line to MAX-CHARS 将命令行的长度限制为MAX-CHARS
--show-limits show limits on command-line length 显示命令行长度的限制
-t, --verbose print commands before executing them 在执行它们之前打印命令
-x, --exit exit if the size (see -s) is exceeded 如果超出大小(请参阅-s),则退出
--help display this help and exit 显示此帮助并退出
--version output version information and exit 输出版本信息并退出

14.2 expr

ARG1 < ARG2 ARG1 is less than ARG2 ARG1小于ARG2
ARG1 <= ARG2 ARG1 is less than or equal to ARG2 ARG1小于或等于ARG2
ARG1 = ARG2 ARG1 is equal to ARG2 ARG1等于ARG2
ARG1 != ARG2 ARG1 is unequal to ARG2 ARG1与ARG2不相等
ARG1 >= ARG2 ARG1 is greater than or equal to ARG2 ARG1大于或等于ARG2
ARG1 > ARG2 ARG1 is greater than ARG2 ARG1大于ARG2
ARG1 + ARG2 arithmetic sum of ARG1 and ARG2 ARG1和ARG2的算术和
ARG1 - ARG2 arithmetic difference of ARG1 and ARG2 ARG1和ARG2的算术差异
ARG1 * ARG2 arithmetic product of ARG1 and ARG2 ARG1和ARG2的算术乘积
ARG1 / ARG2 arithmetic quotient of ARG1 divided by ARG2 ARG1的算术商除以ARG2
ARG1 % ARG2 arithmetic remainder of ARG1 divided by ARG2 ARG1的算术余数除以ARG2



ARG1 | ARG2 ARG1 if it is neither null nor 0, otherwise ARG2 ARG1如果它既不是null也不是0,否则是ARG2
ARG1 & ARG2 ARG1 if neither argument is null or 0, otherwise 0 ARG1如果两个参数都不为null或0,否则为0
STRING : REGEXP anchored pattern match of REGEXP in STRING STRING中REGEXP的锚定模式匹配
match STRING REGEXP same as STRING : REGEXP 与 STRING : REGEXP 相同
substr STRING POS LENGTH substring of STRING, POS counted from 1 STRING的子串,POS从1开始计算
index STRING CHARS index in STRING where any CHARS is found, or 0 STRING中找到任何CHARS的索引,或0
length STRING length of STRING STRING的长度
+ TOKEN interpret TOKEN as a string, even if it is a keyword like 'match' or an operator like '/' 将TOKEN解释为字符串,即使它是像'匹配'这样的关键字或像'/'这样的运算符
( EXPRESSION ) value of EXPRESSION 表达式的值


15. 更多学习相关链接

https://edu.aliyun.com/course/155/lesson/list?utm_content=m_42087
Shell 编程入门到精通 13课时 | 6207人已学 | 阿里云免费课程

Shell 编程范例
项目首页:http://www.tinylab.org/open-shell-book
代码仓库:https://github.com/tinyclub/open-shell-book
在线阅读:http://tinylab.gitbooks.io/shellbook

Linux Shell脚本教程:30分钟玩转Shell脚本编程
http://c.biancheng.net/cpp/shell/

2019-08-04

grep


1. grep
    1.1 grep的与或非举例
    1.2 其他常用例子
    1.3 更多选项
2 正则表达式
    2.1 概念
    2.2 大部分正则表达式的形式都有如下的结构:
    2.3 精确的语法可能因不同的工具或程序而异。
3. 实例
    3.1 查找html文件里所有高度参数
    3.2 删除表格内高度参数
    3.3 写入文件

1. grep

grep – 在文件中搜索模式,打印模式匹配成功的行,可以搜索一个或多个文件。
这里的模式匹配与文本编辑器里的字段搜索,通配符模糊查找不同之处是使用正则表达式,是一套完整的模式表示规则。

1.1 grep的与或非举例

and
$ grep pci hwinfo.txt |grep devices

or -E
$ grep 'pci\|devices' hwinfo.txt
$ grep -E 'pci|devices' hwinfo.txt

非 -v
$ grep -v pci hwinfo.txt

1.2 其他常用例子

单词精确查找 -w
$ grep -w pci hwinfo.txt
仅查找独立的pci单词。即不包括ppci,pci1等前后有其他字母或数字,包含pci的词。

忽略大小写 -i
$ grep -i pci hwinfo.txt

统计行数 -c
$ grep -i pci hwinfo.txt | grep -vc pci-0000

输出包含行号 -n
$ grep -i pci hwinfo.txt | grep -vn pci-0000

打印包含字段的文件名 -l
$ grep -l pci hwinfo.txt s.json
hwinfo.txt

打印不包含字段的文件名 -L
$ grep -L pci hwinfo.txt s.json
s.json

1.3 更多选项


匹配选择: Pattern selection and interpretation: 模式选择和解释:
-E, --extended-regexp PATTERNS are extended regular expressions 使用扩展正则表达式匹配。
-F, --fixed-strings PATTERNS are strings 使用固定字符串匹配。
-G, --basic-regexp PATTERNS are basic regular expressions PATTERNS是基本的正则表达式 (默认)
-P, --perl-regexp PATTERNS are Perl regular expressions PATTERNS是Perl正则表达式

匹配控制:

-e, --regexp=PATTERNS use PATTERNS for matching 使用PATTERNS进行匹配
-f, --file=FILE take PATTERNS from FILE 从文件中获取PATTERNS
-i, --ignore-case ignore case distinctions 忽略案例区别. 忽略大小写
-w, --word-regexp match only whole words 只匹配整个单词. 如果还指定了-x,则此选项无效。
-x, --line-regexp match only whole lines 只匹配整条线
-v, --invert-match select non-matching lines 选择不匹配的行

一般输出控制: Output control:
-c, --count print only a count of selected lines per FILE 仅打印每个FILE所选行的计数. 使用-v,计算不匹配的行。

--color[=WHEN], use markers to highlight the matching strings; 使用标记突出显示匹配的字符串;

--colour[=WHEN] WHEN is 'always', 'never', or 'auto' 什么时候是“永远”,“从不”或“自动”
-L, --files-without-match print only names of FILEs with no selected lines 仅打印没有选定行的FILE名称
-l, --files-with-matches print only names of FILEs with selected lines 仅打印具有选定行的FILE名称
-m, --max-count=NUM stop after NUM selected lines NUM选择行后停止
-o, --only-matching show only nonempty parts of lines that match 仅显示匹配的非线性部分
-q, --quiet, --silent suppress all normal output 抑制所有正常输出
-s, --no-messages suppress error messages 抑制错误消息

输出行前缀控制:

-b, --byte-offset print the byte offset with output lines 输出打印字节偏移量
-H, --with-filename print file name with output lines 打印每个匹配的文件名。当有多个要搜索的文件时,这是默认设置。
-h, --no-filename suppress the file name prefix on output 禁止输出上的文件名前缀。当只有一个文件(或仅标准输入)时,这是默认设置。

--label=LABEL use LABEL as the standard input file name prefix 使用LABEL作为标准输入文件名前缀
-n, --line-number print line number with output lines 输出打印行号
-T, --initial-tab make tabs line up (if needed) 制作标签队列(如果需要). 初始选项卡
-Z, --null print 0 byte after FILE name 在FILE名称后打印0字节。 输出零字节(ASCII NUL字符).

上下文行控制: Context control:
-A, --after-context=NUM print NUM lines of trailing context 打印NUM行尾随上下文
-B, --before-context=NUM print NUM lines of leading context 打印NUM行前导上下文
-C, --context=NUM print NUM lines of output context 打印NUM行输出上下文
-NUM
same as --context=NUM 与--context = NUM​​相同

文件和目录选择:

-a, --text equivalent to --binary-files=text 相当于--binary-files = text; 像处理文本一样处理二进制文件;

--binary-files=TYPE assume that binary files are TYPE; 假设二进制文件是TYPE; TYPE is 'binary', 'text', or 'without-match'
-D, --devices=ACTION how to handle devices, FIFOs and sockets; ACTION is 'read' or 'skip' 如何处理设备,FIFO和插座; ACTION is 'read' or 'skip'
-d, --directories=ACTION how to handle directories; ACTION is 'read', 'recurse', or 'skip' 如何处理目录; ACTION is 'read', 'recurse'递归, or 'skip'

--exclude=GLOB skip files and directories matching GLOB 跳过与GLOB匹配的文件和目录

--exclude-from=FILE skip files matching any file pattern from FILE 跳过与FILE中的任何文件模式匹配的文件

--exclude-dir=GLOB skip directories that match GLOB 跳过与GLOB匹配的目录

--include=GLOB search only files that match GLOB (a file pattern) 仅搜索与GLOB匹配的文件(文件模式)
-I
equivalent to --binary-files=without-match 相当于--binary-files =不匹配; 处理二进制文件,就像它不包含匹配数据一样
-r, --recursive like --directories=recurse 只有符号链接在命令行上时,才能递归地读取每个目录下的所有文件。如果没有给出文件操作数,grep将搜索工作目录。这相当于-d recurse选项
-R, --dereference-recursive likewise, but follow all symlinks 递归地读取每个目录下的所有文件。跟随所有符号链接,与-r不同。

其他选择: Miscellaneous:
-V, --version display version information and exit 显示版本信息并退出

--help display this help text and exit 显示此帮助文本并退出

--line-buffered flush output on every line 在输出上使用行缓冲。这可能会导致性能下降。
-U, --binary do not strip CR characters at EOL (MSDOS/Windows) 不要在EOL(MSDOS/Windows)中删除CR字符。将文件视为二进制文件。
-z, --null-data a data line ends in 0 byte, not newline 将输入和输出数据视为行序列,每个行以零字节(ASCII NUL字符)而不是换行符

2 正则表达式

https://zh.wikipedia.org/wiki/正则表达式
https://en.wikipedia.org/wiki/Regular_expression

2.1 概念

正则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE)(有时称为rational expression理性表达),又称正则表示式、正则表示法、规则表达式、常规表示法,是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。

自20世纪80年代以来,用于编写正则表达式的不同语法已经存在,一个是POSIX标准,另一个是广泛使用的Perl语法。
许多程序设计语言都支持利用正则表达式进行字符串操作。例如,在Perl中就内建了一个功能强大的正则表达式引擎。正则表达式这个概念最初是由Unix中的工具软件(例如sed,awk和grep)普及开的。正则表达式用于搜索引擎,搜索和替换文字处理器和文本编辑器的对话框,文本处理实用程序(如sed和AWK)以及词法分析。许多编程语言都提供内置或通过库的正则表达式功能。

正则表达式(通常称为模式)是用于指定特定目的所需的一组字符串的表达式。指定有限字符串集的简单方法是列出其元素或成员。但是,通常有更简洁的方法来指定所需的字符串集。例如,包含三个字符串“Handel”,“Händel”和“Haendel”的集合可以由模式 H(ä|ae?)ndel 指定。

2.2 大部分正则表达式的形式都有如下的结构:

Boolean "or" 布尔“或”
  • 竖线|代表选择(即或集),具有最低优先级。例如gray|grey可以匹配grey或gray。
Quantification 数量限定
某个字符后的数量限定符用来限定前面这个字符允许出现的个数。最常见的数量限定符包括+、?和*(不加数量限定则代表出现一次且仅出现一次):
  • 问号?代表前面的字符最多只可以出现一次。(0次或1次)。例如,colou?r可以匹配color或者colour;
  • 加号+代表前面的字符必须至少出现一次。(1次或多次)。例如,goo+gle可以匹配google、gooogle、goooogle等;
  • 星号*代表前面的字符可以不出现,也可以出现一次或者多次。(0次、1次或多次)。例如,0*42可以匹配42、042、0042、00042等。
匹配
  • 圆括号()可以用来定义操作符的范围和优先度。例如,gr(a|e)y等价于gray|grey,(grand)?father匹配father和grandfather。
上述这些构造子都可以自由组合,因此H(ae?|ä)ndel和H(a|ae|ä)ndel是相同的。

2.3 精确的语法可能因不同的工具或程序而异。

正则表达式有多种不同的风格。
更多语法及具体规则在可参阅:https://en.wikipedia.org/wiki/Regular_expression

https://en.wikipedia.org/wiki/Comparison_of_regular_expression_engines
正则表达式引擎的比较

正则表达风味比较 - 最流行的正则表达风味的详细比较
http://www.regular-expressions.info/refflavors.html

Regexp语法摘要
http://www.greenend.org.uk/rjk/2002/06/regexp.html

在线正则表达式测试 - 支持Java,JavaScript,.Net,PHP,Python和Ruby
http://www.regexplanet.com/

实现正则表达式 - RE2的作者Russ Cox的系列文章
https://swtch.com/~rsc/regexp/

正则表达式引擎
http://www.softec.lu/site/RegularExpressions/RegularExpressionEngines

3. 实战

3.1 查找html文件里所有高度参数

$ grep height=\"..\" 1.html
<td align="left" height="20">RS</td>
<td align="left" height="23">ORS</td>

3.2 删除表格内高度参数

$ sed 's/height=\"..\">/>/g' 1.html |grep align
<td align="left" >OFS</td>
<td align="left" >RS</td>

3.3 写入文件

$ sed -i 's/height=\"..\">/>/g' 1.html

2019-08-02

awk-sed


1. awk 模式扫描和处理语言
  1.1 awk常用选项
  1.2 awk示例
 1.2.1 抽取2列
 1.2.2 tab键分割列
 1.2.3 筛选包含.html的行
 1.2.4 添加标题,添加内容,上面添加的内容被认为为1个字段,没有tab分割
 1.2.5 拆分
 1.2.6 统计
 1.2.7 统计各个connection状态
 1.2.8 每个用户的进程的占了多少内存
 1.2.9 打印99乘法表
  1.3 awk内置变量
  1.4 print和printf
2. sed 用于过滤和转换文本的流编辑器
  2.1 sed常用选项
  2.2 sed示例
 2.2.1 去掉html里的tag
 2.2.2 去掉html里的高度参数
  2.3 正则表达式的一些最基本的东西
3. 更多参考链接

曾经的上古神器。如今失落的艺术,正被Python等取代。
  • awk (1977)用程序的方式分析文本 模式扫描和处理语言
  • sed (1975)用程序的方式编辑文本 用于过滤和转换文本的流编辑器

1. awk 模式扫描和处理语言

简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本。

1.1 awk常用选项

POSIX options: GNU long options: (standard)
  • -f progfile --file=progfile 指定包含awk程序的文件progfile的路径名。
  • -F fs --field-separator=fs 定义输入字段分隔符。fs是一个字符串或者是一个正则表达式,如-F:。
  • -v var=val --assign=var=val 赋值一个用户定义变量。

1.2 awk示例

1.2.1 抽取2列

$ ls -l |awk '{print $3,$9}'
toma t2.txt
toma temp.html

1.2.2 tab键分割列

$ ls -l |awk '{print $3"\t"$9}'
toma t2.txt
toma temp.html

1.2.3 筛选包含.html的行

$ ls -l |awk -F: '/.html/'
-rw-r--r-- 1 toma users   28240 Apr  6 15:19 systemd.html
-rw-r--r-- 1 toma users   33323 Apr 10 23:23 temp.html

$ ls -l |awk '/.html/{print $3"\t"$9}'

如下3个等效
$ awk '/pci/{print $3"\t"$9}' hwinfo.txt
$ awk '/pci/{print $3,$9}' OFS="\t" hwinfo.txt
$ cat hwinfo.txt | awk '/pci/{print $3,$9}' OFS="\t"

/etc/passwd文件先指定:分割字段,再使用tab分隔输出
$ awk -F ':' '{print $1"\t"$7}' /etc/passwd
$ awk -F ':' '{print $1,$7}' OFS="\t" /etc/passwd
$ awk -F ':' 'BEGIN {print "name,shell"} {print $1,$7} END {print "blue,/bin/nosh"}' OFS="\t" /etc/passwd

1.2.4 添加标题,添加内容,上面添加的内容被认为为1个字段,没有tab分割

$ awk -F ':' 'BEGIN {print "name","shell"} {print $1,$7} END {print "blue","/bin/nosh"}' OFS="\t" /etc/passwd

$ awk -F ':' 'BEGIN {print "name","shell"} {print $1,$7} {print "blue","/bin/nosh"} {print "blue2","/bin/nosh"}' OFS="\t" /etc/passwd

1.2.5 拆分

$ ls -l |awk '{print > $2}' OFS="\t"
不指定列,仅拆分,原样输出,后面的OFS="\t"不起作用。
$ ls -l |awk '{print $2,$3,$5,$9}' OFS="\t" |awk '{print > $1}'
这样即可tab分割后再拆分,或者:
ls -l |awk '{print $2,$3,$5,$9 > $2}' OFS="\t"

若第一列是标题,可参考如下方式
$ awk 'NR!=1{print > $2}' ss0.txt

1.2.6 统计

$ ls -l |awk '{sum+=$5} END {print sum}'
20639404
$ ls -l |awk '{sum+=$5} END {print "size is:",sum/1024/1024,"Mb"}'
size is: 19.6929 Mb
过滤4096大小的文件(一般都是文件夹)
$ ls -l |awk 'BEGIN {size=0;print "[start]size is ", size} {if($5!=4096){size=size+$5;}} END{print "[end]size is ", size/1024/1024,"M"}'
[start]size is  0
[end]size is  19.6499 M

1.2.7 统计各个connection状态

$ awk 'NR!=1{a[$2]++;} END {for (i in a) print i ", " a[i];}' ss0.txt
ESTAB, 732
SYN-SENT, 2

$ awk '{sum[$1]+=1} END {for(k in sum) print k ":" sum[k]}' ss0.txt
$ awk '{sum[$1]+=1} END {for(k in sum) print k ":" sum[k]}' ss0.txt | sort -n -r -k 2 -t ':'

1.2.8 每个用户的进程的占了多少内存

$ ps aux | awk 'NR!=1{a[$1]+=$6;} END { for(i in a) print i ", " a[i]"KB";}'
systemd+, 2316KB
rtkit, 1920KB
polkitd, 14452KB
dbus, 3540KB
toma, 5678404KB
root, 269856KB

1.2.9 打印99乘法表

$ seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i<=NF;i++)printf("%dx%d=%d%s", i, NR, i*NR, i==NR?"\n":"\t")}'
1x1=1
1x2=2 2x2=4
1x3=3 2x3=6 3x3=9
1x4=4 2x4=8 3x4=12 4x4=16
1x5=5 2x5=10 3x5=15 4x5=20 5x5=25
1x6=6 2x6=12 3x6=18 4x6=24 5x6=30 6x6=36
1x7=7 2x7=14 3x7=21 4x7=28 5x7=35 6x7=42 7x7=49
1x8=8 2x8=16 3x8=24 4x8=32 5x8=40 6x8=48 7x8=56 8x8=64
1x9=9 2x9=18 3x9=27 4x9=36 5x9=45 6x9=54 7x9=63 8x9=72 9x9=81

1.3 awk内置变量

awk有许多内置变量用来设置环境信息,这些变量可以被改变,下面给出了最常用的一些变量。

ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk浏览的文件名
FNR 浏览文件的记录数
FS 设置输入域分隔符,等价于命令行 -F选项. 默认是空格或Tab
NF 浏览记录的域的个数. 当前记录中的字段个数,就是有多少列
NR 已读的记录数. 就是行号.
OFS 输出域分隔符. 字段分隔符, 默认也是空格
RS 控制记录分隔符. 默认为换行符
ORS 输出记录分隔符. 默认为换行符
$0 当前记录(这个变量中存放着整个行的内容)
$1~$n 当前记录的第n个字段,字段间由FS分隔

1.4 print和printf

awk中同时提供了print和printf两种打印输出的函数。

其中print函数的参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已。

printf函数,其用法和c语言中printf基本相似,可以格式化字符串,输出复杂时,printf更加好用,代码更易懂。

$ awk -F ':' '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd
$ awk -F ':' '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd

2. sed 用于过滤和转换文本的流编辑器

2.1 sed常用选项

-n, --quiet, --silent suppress automatic printing of pattern space 抑制图案空间的自动打印
--debug annotate program execution 注释程序执行
-e script, --expression=script add the script to the commands to be executed 将脚本添加到要执行的命令中
-f script-file, --file=script-file add the contents of script-file to the commands to be executed 将script-file的内容添加到要执行的命令中
--follow-symlinks follow symlinks when processing in place 在处理时遵循符号链接
-i[SUFFIX], --in-place[=SUFFIX] edit files in place (makes backup if SUFFIX supplied) 编辑文件(如果提供SUFFIX,则进行备份)
-l N, --line-length=N specify the desired line-wrap length for the `l' command 为`l'命令指定所需的换行长度
--posix disable all GNU extensions. 禁用所有GNU扩展。
-E, -r, --regexp-extended use extended regular expressions in the script (for portability use POSIX -E). 在脚本中使用扩展的正则表达式(为了便携性使用POSIX -E)
-s, --separate consider files as separate rather than as a single, continuous long stream. 将文件视为单独的而不是单个连续的长流。
--sandbox operate in sandbox mode (disable e/r/w commands). 在沙箱模式下运行(禁用e / r / w命令)
-u, --unbuffered load minimal amounts of data from the input files and flush the output buffers more often 从输入文件加载最少量的数据并更频繁地刷新输出缓冲区
-z, --null-data separate lines by NUL characters 由NUL字符分隔的行
--help display this help and exit 显示此帮助并退出
--version output version information and exit 输出版本信息并退出

2.2 sed示例

用s命令替换
$ sed "s/my/Hao Chen's/g" pets.txt
注意:上面的sed并没有对文件的内容改变,只是把处理过后的内容输出,如果你要写回文件,你可以使用重定向,如:
$ sed "s/my/Hao Chen's/g" pets.txt > hao_pets.txt
或使用 -i 参数直接修改文件内容:
$ sed -i "s/my/Hao Chen's/g" pets.txt

在每一行最前面加点东西: #
$ sed 's/^/#/g' pets.txt

在每一行最后面加点东西: ---
$ sed 's/$/ --- /g' pets.txt

只替换第3行的文本。
$ sed "3s/my/your/g" pets.txt
只替换第3到第6行的文本。
$ sed "3,6s/my/your/g" pets.txt

只替换每一行的第一个s:
$ sed 's/s/S/1' my.txt

只替换每一行的第二个s:
$ sed 's/s/S/2' my.txt

只替换第一行的第3个以后的s:
$ sed 's/s/S/3g' my.txt

多个匹配
如果我们需要一次替换多个模式,可参看下面的示例:(第一个模式把第一行到第三行的my替换成your,第二个则把第3行以后的This替换成了That)
$ sed '1,3s/my/your/g; 3,$s/This/That/g' my.txt
上面的命令等价于:(注:下面使用的是sed的-e命令行参数)
sed -e '1,3s/my/your/g' -e '3,$s/This/That/g' my.txt

2.2.1 去掉html里的tags

$ sed 's/<[^>]*>//g' html.txt

错误示例: sed 's/<.*>//g' html.txt 会有问题. 上面的'[^>]' 指定了除了>的字符重复0次或多次。

2.2.2 去掉html里的高度参数

查找所有高度参数
$ grep height=\"..\" 1.html
<td align="left" height="20">RS</td>
<td align="left" height="23">ORS</td>

删除表格内高度参数
$ sed 's/height=\"..\">/>/g' 1.html |grep align
<td align="left" >OFS</td>
<td align="left" >RS</td>
写入文件
$ sed -i 's/height=\"..\">/>/g' 1.html

其他命令及操作
a命令就是 append, i命令就是insert,它们是用来添加行的

Pattern Space (模式空间); Hold Space (保留空间)
注意: Append (附加) 与拷贝不同,会附加到目标位置原始内容换行后.
  • g: 将hold space中的内容拷贝到pattern space中,原来pattern space里的内容清除
  • G: 将hold space中的内容append到pattern space\n后
  • h: 将pattern space中的内容拷贝到hold space中,原来的hold space里的内容被清除
  • H: 将pattern space中的内容append到hold space\n后
  • x: 交换pattern space和hold space的内容



2.3 正则表达式的一些最基本的东西


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


3. 更多参考链接

https://coolshell.cn/articles/9070.html
AWK 简明教程

内建变量,参看: http://www.gnu.org/software/gawk/manual/gawk.html#Built_002din-Variables
流控方面,参看: http://www.gnu.org/software/gawk/manual/gawk.html#Statements
内建函数,参看: http://www.gnu.org/software/gawk/manual/gawk.html#Built_002din
正则表达式,参看:http://www.gnu.org/software/gawk/manual/gawk.html#Regexp

https://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html

https://coolshell.cn/articles/9104.html
SED 简明教程
http://www.gnu.org/software/sed/manual/sed.html

https://zh.wikipedia.org/wiki/正则表达式
https://en.wikipedia.org/wiki/Regular_expression

Diode

导航 (返回顶部) 1. Diode 1.1 Diode 概述 1.2 肖克利二极管方程 1.3 缩写 Abbreviations 2. 主要功能 2.1 单向电流 (Unidirectional current flow) 2.2 阈值电压 (Threshold...