本文共 5305 字,大约阅读时间需要 17 分钟。
contents
== 0. 待修改 ==
shell 脚本最常见的一个用途就是处理文本文件。检查日志文件、读取配置文件、处理数据元素,shell 脚本可以帮助我们将文本中各种数据的日常处理任务自动化。
sed 和 gawk 工具能够简化数据处理任务。
1. 文本处理
1.1 sed 编辑器
与普通交互式文本编辑器恰好相反,它是一种轻量级流编辑器。
- 交互式文本编辑器中,你可以使用键盘来插入、删除、替换数据。
- 流编辑器中,在编辑数据前会基于预先提供的规则来编辑数据流。
sed 编辑器可以根据命令来处理数据流中的数据,那些命令要么从命令行中输入,要么存储在一个命令文本文件中。要注意的是,它不仅能够修改文件内容,还能修改命令的结果。
sed 编辑器会执行如下操作:
- 一次从输入中读取一行数据。
- 根据所提供的编辑器命令匹配数据。
- 按照命令修改流中的数据。
- 将新的数据输出到 STDOUT
它会将文件中的每一行数据都进行处理,遍历完毕所有的数据行后,它就会终止。
sed 编辑器只需要对数据流进行一遍处理就可以完成编辑操作,效率比交互式编辑器高,可以快速完成对数据的自动修改。sed options script file
options | descriptions |
---|---|
-n | 一般sed命令会把所有数据都输出到屏幕,如果加入此选项,则只会把经过sed命令处理的行输出到屏幕 |
-e script | 允许对输入数据应用多条sed命令编辑,将script中指定的命令添加到已有的命令中 |
-f file | 允许对输入数据应用多条sed命令编辑, 将file中指定的命令添加到已有的命令中 |
-i | 用sed修改结果直接修改读取数据的文件,而不是由屏幕输出 |
除了 -i
选项,命令只针对屏幕输出进行修改操作。
script | descriptiongs |
---|---|
a \ | 追加,在当前行后添加一行或多行,添加多行时,除最后一行外,每行末尾需要用 \ 代表数据未完结 |
c \ | 行替换,用c后面的字符串替换原数据行,替换多行时,除最后一行外,每行末尾用 \ 代表数据未完结 |
i \ | 插入,在当前行前插入一行或多行。插入多行时,除最后一行外,每行末尾需要用 \ 代表数据未完结 |
d | 删除指定行 |
p | 输出指定行 |
s | 字符替换,用一个字符串替换另外一个字符串 |
1.1.1 在命令行定义编辑器命令
默认情况下,sed 编辑器会将指定的命令应用到 STDIN 输入流上,这样你可以直接将数据通过管道输入 sed 编辑器处理。
$ echo "This is a test." | sed 's/test/big test/' # 斜线间指定的第二个文本字符串来替换第一个文本字符串模式This is a big test.
sed 's/test/big test' data.txt
针对文件的每行内容进行处理。
1.1.2 在命令行使用多个编辑器命令
使用 -e
选项。
sed -e 's/brown/green/; s/dog/cat/' data.txt # 命令之间用分号隔开,命令末尾和分号之间不能有空格。
或者也可以采用下面的形式:
sed -e ' # 次提示符起始,输入每行命令s/brown/green/s/fox/elephant/s/dog/cat/' data.txt # 次提示符结束
将指定的每条命令应用到文本文件中的每一行上。
1.1.3 从文件中读取编辑器命令
使用 -f
参数来指定命令文件,不用在每条命令后面放一个分号,sed 编辑器知道每行都是一条单独的命令,sed 编辑器会从指定文件中读取命令,并将它们应用到数据文件中的每一行上。
# script.seds/brown/green/s/fox/elephant/s/dog/cat/
sed -f script.sed data.txt
1.2 gawk 程序
一种编程语言。
- 定义变量来保存数据
- 使用算数和字符操作符来处理数据
- 使用结构化编程概念来为数据处理增加逻辑
- 通过提取数据文件中的数据元素,将其重新排列或格式化,生成格式化报告
生成格式化日志文件,gawk 程序可以让你从日志文件中过滤出需要的数据元素,然后你可以将其格式化,使得重要的数据更易于阅读。
1.2.1 gawk 命令格式
gawk options program file
options | descriptions |
---|---|
-F fs | 指定行中划分数据字段的字段分隔符 |
-f file | 从指定的文件中读取程序 |
-v variable | 定义 gawk 程序中的一个变量及其默认值 |
-mf N | 指定要处理的数据文件中的最大子段数量 |
-mr N | 指定数据文件中的最大数据行数 |
-W keyword | 指定gawk的兼容模式或警告等级 |
gawk 的强大之处在于它可以写脚本来读取文本行的数据,然后处理并显示数据。
1.2.2 从命令行读取程序脚本
gawk 程序脚本用一对花括号来定义,命令行假定脚本是个单个文本字符串,你需要将脚本放到单引号中。如果没有在命令行上指定文件名,gawk 程序会从 STDIN 接受数据,意味着你还需要手动输入字符串供其处理。
Ctrl +D组合键产生一个 EOF 字符,能够终止字符串的输入。
1.2.3 使用数据字段变量
- $0 代表整个文本行
- $1 代表文本行中的第1个数据字段
- $2 代表文本行中的第2个数据字段
- $n 代表文本行中的第n个数据字段
在文本行中,每个数据字段都是通过字段分隔符划分的。gawk 在读取一行文本时,会用预定义的字段分隔符划分每个数据字段。gawk 中默认的字段分隔符时任意的空白字符(例如空格或制表符)。
#data.txtOne line of test text.Two lines of test text.Three lines of test text.
只显示第一个字段的值。
$ gawk '{print $1}' data.txtOneTwoThree
读取使用 :
分隔符的文件。
gawk -F: '{print $1}' /etc/passwd
1.2.4 在程序脚本中使用多个命令
gawk 编程语言允许你将多条命令组合成一个正常的程序。
$ echo 'My name is Rich' | gawk '{ $4="Christine"; print $0}'My name is Christine
gawk '{$4="Christine"print $0}'My name is RichMy name is Christine
要想退出程序,Ctrl+D。
1.2.5 从文件中读取程序
# script.gawk{ print $1 "'s home directory is " $6}
gawk -F: -f script.gawk /etc/passwd
# script.gawk{ text = "'s home directory is "print $1 text $6}
gawk 中引用变量并不需要使用美元符。
1.2.6 在处理数据前运行脚本
BEGIN 关键字可以强制 gawk 在读取数据前执行 BEGIN 关键字后指定的程序脚本。
gawk 'BEGIN {print "Hello World!"}'
gawk 'BEGIN {print "The data File Contents"}{print $0}' data.txt
1.2.7 在处理数据后运行脚本
gawk 'BEGIN {print "The data File Contents"}{print $0}END {print "End of File"}' data.txt
从数据文件中生成报告脚本:
# script.gawkBEGIN { print "The latest list of users and shells"print " UserID \t Shell"print "--------\t---------"FS=":"{ print $1 " \t " $7}END { print "This concludes the listing"}
2. sed 编辑器基础
2.1 更多的替换选项
2.1.1 替换标记
默认替换只会替换每行出现的第一个文本。
s/pattern/replacement/flags
- 数字,表明新文本将替换第几处模式匹配的地方。
- g,表明新文本将会替换所有匹配的文本。
- p,表明原先行的内容要打印出来。
- w file,将替换的结果写到文件中。
2.1.2 替换字符
用 C shell 替换 bash shell。
sed 's!/bin/bash!/bin/csh!' /etc/passwd
感叹号被用作字符串分隔符。
2.2 使用地址
默认情况下,sed 命令会作用于全部行,如果想指定特定行,需要使用行寻址。
- 以数字形式表示行区间
- 用文本模式来过滤出行
2.2.1 以数字方式的行寻址
sed '2s/dog/cat/' data.txt
只修改第二行文本。
sed '2,3s/dog/cat/' data.txt
指定行区间。
sed '2,$s/dog/cat/' data.txt
从第二行开始的所有行。
2.2.2 使用文本过滤器
pattern/command
还是使用正则表达式好一些。
2.2.3 命令组合
sed '2{s/fox/elephant/s/dog/cat/}' data.txt
两条命令都会作用在该地址上。
sed '3,${s/fox/elephant/s/dog/cat/}' data.txt
2.3 删除行
sed 'd' data.txt
删除所有行。
sed '3d' data.txt
删除第 3 行。
sed '2,3d' data.txt
指定行区间。
… sed 编辑器不会修改原始文件,除非你写入原文件。2.4 插入和附加文本
- 插入(i):会在指定行前增加一个新行
- 附加(a):会在指定行后增加一个新行
sed '[address]command\newline'
echo "Test Line 2" | sed "i\Test Line 1"Test Line 1Test Line 2
将一个新行插入到数据流第 3 行前。
sed '3i\This is an inserted line.' data.txt
$ 符号同样适用。
…
2.5 修改行
sed '3c\This is an inserted line.' data.txt
文本模式修改:
sed '/number 3/c\This is an inserted line.' data.txt
使用地址区间?
sed '2,3c\This is an inserted line.' data.txt
…
sed 编辑器会用一行文本来替换数据流中的两行文本。
2.6 转换命令
[address]y/inchars/outchars/
可以处理单个字符。
sed 'y/123/789/' data.txt
用7来替换1,用8来替换2,用9来替换3。
全局命令。2.7 回顾打印
- p 命名用来打印文本行
- 等号命令用来打印行号
- l 用来列出行
2.7.1 打印行
echo "this is a test" | sed 'p'
打印包含有匹配文本模式的行:
sed -n '/number 3/p' data.txt
-n 选项可以禁止输出其他行。
sed -n '2,3p' data.txt
2.7.2 打印行号
sed '=' data.txt
sed -n '/number 4/{=p}' data.txt
2.7.3 列出行
命令(l)能够打印数据流中的文本和不可打印的ASCII字符。
sed 'l' data.txt
2.8 使用 sed 处理文件
2.8.1 写入文件
[address]w filename
w 命令用来向文件写入行。
sed '1,2w test.txt' data.txt
将数据流(data.txt)中的前两行打印到一个文本文件(text.txt)中。
2.8.2 从文件读取数据
将一个独立文件中的数据插入到数据流中。
[address]r filename
sed '3r data.txt' data.txt
转载地址:https://jiaming.blog.csdn.net/article/details/104942978 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!