shell 初识sed和gawk

初识sed和gawk


文本处理

sed编辑器

sed 编辑器被称作流编辑器(stream editor),与普通的交互式文本编辑器截然不同。在交互 式文本编辑器(比如 Vim)中,可以用键盘命令交互式地插入、删除或替换文本数据。

sed 编辑器根据命令来处理数据流中的数据,这些命令要么从命令行中输入,要么保存在命 令文本文件中。sed 编辑器可以执行下列操作。

  1. 从输入中读取一行数据。
  2. 根据所提供的编辑器命令匹配数据。
  3. 按照命令修改数据流中的数据。
  4. 将新的数据输出到 STDOUT。

sed 命令的格式如下。 sed options file

选项描述
-e commands在处理输入时,加入额外的 sed 命令
-f file在处理输入时,将 file 中指定的命令添加到已有的命令中
-n不产生命令输出,使用 p(print)命令完成输出

在命令行中定义编辑器命令

$ echo "This is a test" | sed 's/test/big test/' 
This is a big test

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

$ sed -e 's/brown/red/; s/dog/cat/' data1.txt 
The quick red fox jumps over the lazy cat. 
The quick red fox jumps over the lazy cat. 
The quick red fox jumps over the lazy cat. 
The quick red fox jumps over the lazy cat.

从文件中读取编辑器命令

$ cat script1.sed 
s/brown/green/ 
s/fox/toad/ 
s/dog/cat/
$
$ sed -f script1.sed data1.txt
The quick green toad jumps over the lazy cat. 
The quick green toad jumps over the lazy cat. 
The quick green toad jumps over the lazy cat. 
The quick green toad jumps over the lazy cat. 
$

gawk编辑器

gawk 是 Unix 中最初的 awk 的 GNU 版本。gawk 比 sed 的流编辑提升了一个“段位”,它提 供了一种编程语言,而不仅仅是编辑器命令。在 gawk 编程语言中,可以实现以下操作

  • 定义变量来保存数据。
  • 使用算术和字符串运算符来处理数据。
  • 使用结构化编程概念(比如 if-then 语句和循环)为数据处理添加处理逻辑。
  • 提取文件中的数据将其重新排列组合,最后生成格式化报告。

gawk 的基本格式如下。 gawk options program file

选项描述
-F fs指定行中划分数据字段的字段分隔符
-f file从指定文件中读取 gawk 脚本代码
-v var=value定义 gawk 脚本中的变量及其默认值
-L [keyword]指定 gawk 的兼容模式或警告级别

sed编辑器基础命令

更多的替换选项

替换标志

有 4 种可用的替换标志。

  • 数字,指明新文本将替换行中的第几处匹配。
  • g,指明新文本将替换行中所有的匹配。
  • p,指明打印出替换后的行。
  • w file,将替换的结果写入文件。
$ cat data4.txt 18 This is a test of the test script.
This is the second test of the test script.
$
$ sed 's/test/trial/' data4.txt
This is a trial of the test script.
This is the second trial of the test script. 
$
$ sed 's/test/trial/2' data4.txt
This is a test of the trial script.
This is the second test of the trial script. 
$
$ sed 's/test/trial/g' data4.txt
This is a trial of the trial script.
This is the second trial of the trial script.
$
$ cat data5.txt
This is a test line.
This is a different line.
$
$ sed -n 's/test/trial/p' data5.txt This is a trial line.
$
$ sed 's/test/trial/w test.txt' data5.txt This is a trial line.
This is a different line.
$
$ cat test.txt
This is a trial line. 
$

替代字符

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

使用地址

在 sed 编辑器中有两种形式的行寻址。

  • 以数字形式表示的行区间。
  • 匹配行内文本的模式。
$ cat data1.txt
The quick brown fox jumps over the lazy dog. 
The quick brown fox jumps over the lazy dog. 
The quick brown fox jumps over the lazy dog. 
The quick brown fox jumps over the lazy dog. 
$
$ sed '2s/dog/cat/' data1.txt
The quick brown fox jumps over the lazy dog. 
The quick brown fox jumps over the lazy cat. 
The quick brown fox jumps over the lazy dog. 
The quick brown fox jumps over the lazy dog. 
$
The quick brown fox jumps over the lazy dog.
$ sed '2,3s/dog/cat/' data1.txt
The quick brown fox jumps over the lazy dog. 
The quick brown fox jumps over the lazy cat. 
The quick brown fox jumps over the lazy cat.
The quick brown fox jumps over the lazy dog.
$
$ sed '2,$s/dog/cat/' data1.txt 
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy cat.
The quick brown fox jumps over the lazy cat.
The quick brown fox jumps over the lazy cat.
$

使用文本模式过滤

$ grep /bin/bash /etc/passwd 
root:x:0:0:root:/root:/bin/bash 
christine:x:1001:1001::/home/christine:/bin/bash 
rich:x:1002:1002::/home/rich:/bin/bash
$
$ sed '/rich/s/bash/csh/' /etc/passwd 
root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin 
[...] 
christine:x:1001:1001::/home/christine:/bin/bash 
sshd:x:126:65534::/run/sshd:/usr/sbin/nologin 
rich:x:1002:1002::/home/rich:/bin/csh
$

命令组

$ sed '2{
> s/fox/toad/
> s/dog/cat/
> }' data1.txt
The quick brown fox jumps over the lazy dog. 
The quick brown toad jumps over the lazy cat. 
The quick brown fox jumps over the lazy dog. 
The quick brown fox jumps over the lazy dog. 
$

删除行

文本替换命令并非 sed 编辑器唯一的命令。如果需要删除文本流中的特定行,可以使用删除 (d)命令。

$ cat data6.txt
This is line number 1. 
This is line number 2.
This is the 3rd line. 
This is the 4th line. 
$
$ sed '3d' data6.txt 
This is line number 1.
This is line number 2. 
This is the 4th line. 
$

记住,sed 编辑器不会修改原始文件。你删除的行只是从 sed 编辑器的输出中消失了。原 始文件中仍然包含那些“被删掉”的行。

插入和附加文本

如你所望,跟其他编辑器类似,sed 编辑器也可以向数据流中插入和附加文本行。这两种操 作的区别可能比较费解。

  • 插入(insert)(i)命令会在指定行前增加一行。
  • 附加(append)(a)命令会在指定行后增加一行。
$ cat data6.txt
This is line number 1.
This is line number 2.
This is the 3rd line.
This is the 4th line.
$
$ sed '3i\
> This is an inserted line.
> ' data6.txt
This is line number 1. 
This is line number 2. 
This is an inserted line. 
This is the 3rd line. 
This is the 4th line.
$

修改行

$ sed '2c\
> This is a changed line of text. > ' data6.txt
This is line number 1.
This is a changed line of text. This is the 3rd line.
This is the 4th line.
$

转换命令

转换(y)命令是唯一可以处理单个字符的 sed 编辑器命令。该命令格式如下所示

[address]y/inchars/outchars/

$ cat data9.txt
This is line 1.
This is line 2.
This is line 3.
This is line 4.
This is line 5.
This is line 1 again.
This is line 3 again.
This is the last file line. $
$ sed 'y/123/789/' data9.txt This is line 7.
This is line 8.
This is line 9.
This is line 4.
This is line 5.
This is line 7 again.
This is line 9 again.
This is the last file line.
$

实战

#!/bin/bash
# Change the shebang used for a directory of scripts

################## Function Declarations ##########################

function errorOrExit {
	echo
	echo $message1
	echo $message2
	echo "Exiting script..."
	exit
}

function modifyScripts {
	echo
	read -p "Directory name in which to store new scripts? " newScriptDir
	
	echo "Modifying the scripts started at $(date +%N) nanoseconds"
	
	count=0
	for filename in $(grep -l "/bin/sh" $scriptDir/*.sh)
	do
		newFilename=$(basename $filename)
		cat $filename | 
		sed '1c\#!/bin/bash' > $newScriptDir/$newFilename
		count=$[$count + 1] 
	done
	echo "$count modifications completed at $(date +%N) nanoseconds"
}

################# Check for Script Directory ######################
if [ -z $1 ]
then 
	message1="The name of the directory containing scripts to check"
	message2="is missing. Please provide the name as a parameter."
        errorOrExit
else
	scriptDir=$1
fi 

################ Create Shebang Report ############################

sed -sn '1F; 
1s!/bin/sh!/bin/bash!' $scriptDir/*.sh | 
gawk 'BEGIN {print ""
print "The following scripts have /bin/sh as their shebang:"
print "==================================================="}
{print $0}
END {print ""
print "End of Report"}'

################## Change Scripts? #################################

echo
read -p "Do you wish to modify these scripts' shebang? (Y/n)? " answer

case $answer in
Y | y)
	modifyScripts
	;;
N | n)
	message1="No scripts will be modified."
	message2="Run this script later to modify, if desired."
	errorOrExit
	;;
*)
	message1="Did not answer Y or n."
	message2="No scripts will be modified."
	errorOrExit
	;;
esac

小结

虽然 shell 脚本本身就能完成不少工作,但在处理数据时往往会有困难。为此,Linux 提供了 两款方便的工具。sed 是一款流编辑器,可以在读取数据时快速地即时进行处理,但你必须给 sed 编辑器指定用于处理数据的编辑命令。

gawk 程序是一款来自 GNU 组织的实用工具,它模仿并扩展了 Unix 中 awk 程序的功能。gawk 内建了编程语言,可用来编写数据处理脚本。gawk 脚本可以从大型数据文件中提取数据元素,并 将其按照需要的格式输出。这非常有助于处理大型日志文件以及从数据文件中生成定制报表。

使用 sed 和 gawk 的关键在于懂得正则表达式。在提取和处理文本文件数据时,正则表达式 是创建定制过滤器的关键。第 20 章将深入探索经常被人们误解的正则表达式,演示如何构建正 则表达式,以处理各种各样的数据

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值