Linux 中最常用的文本处理编辑器 —— 初识 sed 和 gawk

contents

    • 文本处理
    • sed 编辑器
      • 在命令行定义编辑器命令
      • 在命令行使用多个编辑器命令
      • 从文件中读取编辑器命令
    • gawk 程序
      • gawk 命令格式
      • 从命令行读取程序脚本
      • 使用数据字段变量
      • 在程序脚本中使用多个命令
      • 从文件中读取程序
      • 在处理数据前运行脚本
      • 在处理数据后运行脚本
  • sed 编辑器基础
    • 更多的替换选项
      • 替换标记
      • 替换字符
    • 使用地址
      • 以数字方式的行寻址
      • 使用文本过滤器
      • 命令组合
    • 删除行
    • 插入和附加文本
    • 修改行
    • 转换命令
    • 回顾打印
      • 打印行
      • 打印行号
      • 列出行
    • 使用 sed 处理文件
      • 写入文件
      • 从文件读取数据

shell 脚本最常见的一个用途就是处理文本文件。检查日志文件、读取配置文件、处理数据元素,shell 脚本可以帮助我们将文本中各种数据的日常处理任务自动化。

sed 和 gawk 工具能够简化数据处理任务。

文本处理

sed 编辑器

与普通交互式文本编辑器恰好相反,它是一种轻量级流编辑器。

  • 交互式文本编辑器中,你可以使用键盘来插入、删除、替换数据。
  • 流编辑器中,在编辑数据前会基于预先提供的规则来编辑数据流。

sed 编辑器可以根据命令来处理数据流中的数据,那些命令要么从命令行中输入,要么存储在一个命令文本文件中。要注意的是,它不仅能够修改文件内容,还能修改命令的结果。

sed 编辑器会执行如下操作:

  1. 一次从输入中读取一行数据。
  2. 根据所提供的编辑器命令匹配数据。
  3. 按照命令修改流中的数据。
  4. 将新的数据输出到 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 字符替换,用一个字符串替换另外一个字符串

在命令行定义编辑器命令

默认情况下,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

针对文件的每行内容进行处理。

在命令行使用多个编辑器命令

使用 -e 选项。

sed -e 's/brown/green/; s/dog/cat/' data.txt

命令末尾和分号之间不能有空格。

或者也可以采用下面的形式:

sed -e '
s/brown/green/
s/fox/elephant/
s/dog/cat/' data.txt

从文件中读取编辑器命令

# script.sed
s/brown/green/
s/fox/elephant/
s/dog/cat/
sed -f script.sed data.txt

gawk 程序

一种编程语言。

  • 定义变量来保存数据
  • 使用算数和字符操作符来处理数据
  • 使用结构化编程概念来为数据处理增加逻辑
  • 通过提取数据文件中的数据元素,将其重新排列或格式化,生成格式化报告

gawk 命令格式

gawk options program file
options descriptions
-F fs 指定行中划分数据字段的字段分隔符
-f file 从指定的文件中读取程序
-v variable 定义 gawk 程序中的一个变量及其默认值
-mf N 指定要处理的数据文件中的最大子段数量
-mr N 指定数据文件中的最大数据行数
-W keyword 指定gawk的兼容模式或警告等级

gawk 的强大之处在于它可以写脚本来读取文本行的数据,然后处理并显示数据。

从命令行读取程序脚本

gawk 程序脚本用一对花括号来定义,命令行假定脚本是个单个文本字符串,你需要将脚本放到单引号中。如果没有在命令行上指定文件名,gawk 程序会从 STDIN 接受数据,意味着你还需要手动输入字符串供其处理。

Ctrl +D组合键产生一个 EOF 字符,能够终止字符串的输入。

使用数据字段变量

  • $0 代表整个文本行
  • $1 代表文本行中的第1个数据字段
  • $2 代表文本行中的第2个数据字段
  • $n 代表文本行中的第n个数据字段

在文本行中,每个数据字段都是通过字段分隔符划分的。gawk 在读取一行文本时,会用预定义的字段分隔符划分每个数据字段。gawk 中默认的字段分隔符时任意的空白字符(例如空格或制表符)。

#data.txt
One line of test text.
Two lines of test text.
Three lines of test text.

只显示第一个字段的值。

$ gawk '{print $1}' data.txt
One
Two
Three

读取使用 : 分隔符的文件。

gawk -F: '{print $1}' /etc/passwd

在程序脚本中使用多个命令

gawk 编程语言允许你将多条命令组合成一个正常的程序。

$ echo 'My name is Rich' | gawk '{
     $4="Christine"; print $0}'
My name is Christine
gawk '{
$4="Christine"
print $0}'
My name is Rich
My name is Christine

要想退出程序,Ctrl+D。

从文件中读取程序

# 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 中引用变量并不需要使用美元符。

在处理数据前运行脚本

BEGIN 关键字可以强制 gawk 在读取数据前执行 BEGIN 关键字后指定的程序脚本。

gawk 'BEGIN {print "Hello World!"}'
gawk 'BEGIN {print "The data File Contents"}
{print $0}' data.txt

在处理数据后运行脚本

gawk 'BEGIN {print "The data File Contents"}
{print $0}
END {print "End of File"}' data.txt

从数据文件中生成报告脚本:

# script.gawk
BEGIN {
     
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"
}

sed 编辑器基础

更多的替换选项

替换标记

默认替换只会替换每行出现的第一个文本。

s/pattern/replacement/flags
  • 数字,表明新文本将替换第几处模式匹配的地方。
  • g,表明新文本将会替换所有匹配的文本。
  • p,表明原先行的内容要打印出来。
  • w file,将替换的结果写到文件中。

替换字符

用 C shell 替换 bash shell。

sed 's!/bin/bash!/bin/csh!' /etc/passwd

感叹号被用作字符串分隔符。

使用地址

默认情况下,sed 命令会作用于全部行,如果想指定特定行,需要使用行寻址。

  • 以数字形式表示行区间
  • 用文本模式来过滤出行

以数字方式的行寻址

sed '2s/dog/cat/' data.txt

只修改第二行文本。

sed '2,3s/dog/cat/' data.txt

指定行区间。

sed '2,$s/dog/cat/' data.txt

从第二行开始的所有行。

使用文本过滤器

还是使用正则表达式好一些。

命令组合

sed '2{
s/fox/elephant/
s/dog/cat/
}' data.txt

两条命令都会作用在该地址上。

sed '3,${
s/fox/elephant/
s/dog/cat/
}' data.txt

删除行

sed 'd' data.txt

删除所有行。

sed '3d' data.txt

删除第三行。

sed '2,3d' data.txt

指定行区间。
sed 编辑器不会修改原始文件,除非你写入原文件。

插入和附加文本

  • 插入(i):会在指定行前增加一个新行
  • 附加(a):会在指定行后增加一个新行
echo "Test Line 2" | sed "i\Test Line 1"
Test Line 1
Test Line 2

将一个新行插入到数据流第三行前。

sed '3i\
This is an inserted line.' data.txt

$ 符号同样适用。

修改行

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 编辑器会用一行文本来替换数据流中的两行文本。

转换命令

可以处理单个字符。

sed 'y/123/789/' data.txt

用7来替换1,用8来替换2,用9来替换3。

回顾打印

  • p 命名用来打印文本行
  • 等号命令用来打印行号
  • l 用来列出行

打印行

echo "this is a test" | sed 'p'

打印包含有匹配文本模式的行:

sed -n '/number 3/p' data.txt

-n 选项可以禁止输出其他行。

sed -n '2,3p' data.txt

打印行号

sed '=' data.txt
sed -n '/number 4/{
=
p
}' data.txt

列出行

命令(l)能够打印数据流中的文本和不可打印的ASCII字符。

sed 'l' data.txt

使用 sed 处理文件

写入文件

[address]w filename

w 命令用来向文件写入行。

sed '1,2w test.txt' data.txt

将数据流(data.txt)中的前两行打印到一个文本文件(text.txt)中。

从文件读取数据

将一个独立文件中的数据插入到数据流中。

[address]r filename
sed '3r data.txt' data.txt

你可能感兴趣的:(#,高级,shell,脚本)