当前位置: 首页 > news >正文

【Linux命令行与Shell脚本编程】第十八章 文本处理与编辑器基础

Linux命令行与Shell脚本编程

第十八章 文本处理与编辑器基础

文章目录

  • Linux命令行与Shell脚本编程
    • 第十八章 文本处理与编辑器基础
  • 文本处理与编辑器基础
    • 8.1.文本处理
      • 8.1.1.sed编辑器
        • 8.1.1.1.在命令行中定义编辑器命令
        • 8.1.1.2.在命令行中使用多个编辑器命令
        • 8.1.1.3.从文件中读取编辑器命令
      • 8.1.2.gawk编辑器
        • 8.1.2.1.gawk命令格式
        • 8.1.2.2.从命令行读取gawk脚本
        • 8.1.2.3.使用数据字段变量
        • 8.1.2.4.在脚本中使用多条命令
        • 8.1.2.5.从文件中读取脚本
        • 8.1.2.6.在处理数据前运行脚本
        • 8.1.2.7.在处理数据后运行脚本
    • 8.2.sed编辑器基础命令
      • 8.2.1.更多的替换选项
        • 8.2.1.1.替换标志
        • 8.2.1.2.替换字符
      • 8.2.2.使用地址
        • 8.2.2.1.数字形式行寻址
        • 8.2.2.2.使用文本模式过滤
        • 8.2.2.3.命令组
      • 8.2.3.删除行(d)
      • 8.2.4.插入和附加文本(a\i)
        • 插入与附加
        • 添加多行
      • 8.2.5.修改行(c)
      • 8.2.6.转换命令(y)
      • 8.2.7.打印
        • 打印行(p)
        • 打印行号(=)
        • 列出行(l)
      • 8.2.8.处理文件
        • 写入文件(w)
        • 读取数据(r)
        • 文件夹下文件


文本处理与编辑器基础

  • 文本处理
  • 学习sed编辑器
  • sed编辑器基础命令
  • gawk编辑器入门
  • sed编辑器基础

shell脚本可以将文本文件中各种数据的日常处理任务自动化Linux中的sed和gawk两款工具能够极大地简化数据处理任务。

8.1.文本处理

想要即时处理文本文件中的文本,有一个可以自动格式化、插入、修改或删除文本元素的简单的命令行编辑器。
有两款常见工具sed和gawk。

8.1.1.sed编辑器

sed编辑器(stream editor)流编辑器.
在交互式文本编辑器(比如Vim)中,可以用键盘命令交互式地插入、删除或替换文本数据。
流编辑器则是根据事先设计好的一组规则编辑数据流。

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

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

在流编辑器匹配并对一行数据执行所有命令后,会读取下一行数据并重复执行。在流编辑器处理完数据流中的所有行后,就结束运行。

sed命令格式:

sed options script file

options参数允许修改sed命令的行为:

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

script参数指定了应用于流数据中的单个命令。
如果需要多个命令,则使用-e选项在命令行中指定,或使用-f选项在单独的文件中指定。

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

默认情况下,sed编辑器会将指定的命令应用于STDIN输入流中。因此,可以直接将数据通过管道传入sed编辑器进行处理.

s 替换命令:替换命令会用斜线间指定的第二个字符串替换第一个字符串。

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

sed编辑器的强大之处是可以同时对数据做出多处修改.

$ cat data1.txt
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
$ sed 's/dog/cat/' data1.txt
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.
The quick brown fox jumps over the lazy cat.

sed命令几乎瞬间就执行完毕并返回数据。在处理每行数据的同时,结果也随之显现。在sed编辑器处理完整个文件之前就能看到结果。

重要的是sed编辑器并不会修改文本文件的数据。它只是将修改后的数据发送到STDOUT !!!

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

使用-e选项在sed命令行中执行多个命令.

$ 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.

命令之间必须以分号 ; 分隔,命令末尾和分号之间不能出现空格。
也可以用bash shell中的次提示符来分隔命令。输入第一个单引号标示出sed程序脚本的起始.
要在闭合单引号所在行结束命令。bash shell一旦发现了闭合单引号,就会执行命令.

$ sed -e '
> s/brown/green/
> s/fox/toad/
> s/dog/cat/' 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.

8.1.1.3.从文件中读取编辑器命令

将量要执行的sed命令放进单独的文件通常会更方便.
在sed命令中用-f选项来指定文件:

$ 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.

不用在每条命令后面加分号。sed编辑器将每一行作为一条单独的命令。
sed编辑器脚本文件容易与bash shell脚本文件混淆。可以使用.sed作为sed脚本文件的扩展名。

更多sed命令 sed编辑器基础命令

8.1.2.gawk编辑器

虽然sed编辑器非常方便,可以即时修改文本文件,但其自身也存在一些局限。
往往还需要一款更高级的文本文件处理工具能够提供一个更贴近编程的环境,修改和重新组织文件中的数据。

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

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

gawk的报告生成能力多用于从大文本文件中提取数据并将其格式化成可读性报告。
最完美的应用案例是格式化日志文件。gawk能够从日志文件中过滤出所需的数据,将其格式化,以便让重要的数据更易于阅读。

8.1.2.1.gawk命令格式

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

gawk可以编写脚本来读取文本行中的数据,然后对其进行处理并显示,形成各种输出报告。

8.1.2.2.从命令行读取gawk脚本

gawk脚本用一对花括号来定义。必须将脚本命令放到一对单引号与花括号 ‘{}’ 之间。
gawk命令行假定脚本是单个文本字符串,因此必须将脚本放到单引号中。

没有在命令行中指定文件名时,gawk程序会从STDIN接收数据。在脚本运行时,会一直等待来自STDIN的文本。

$ gawk '{print "Hello World!"}'
This is a test
Hello World!
hello
Hello World!
Goodbye
Hello World!
This is another test
Hello World!

脚本定义了一个命令:print:将文本打印到STDOUT。
在脚本运行时,会一直等待来自STDIN的文本。如果输入一行文本并按下Enter键,则gawk会对这行文本执行一遍脚本。
和sed编辑器一样,gawk会对数据流中的每一行文本都执行脚本。

bash shell提供了Ctrl+D组合键来生成EOF(end-of-file)字符终止gawk程序,表明数据流已经结束。
使用该组合键可以终止gawk程序并返回到命令行界面。

8.1.2.3.使用数据字段变量

gawk处理文本文件中的数据时会自动为每一行的各个数据元素分配一个变量。
在默认情况下,gawk会将下列变量分配给文本行中的数据字段。

  • $0代表整个文本行。
  • $n(1~n)代表文本行中的第n个数据字段。

文本行中的数据字段通过字段分隔符来划分。
读取一行文本时,gawk会用预先定义好的字段分隔符划分出各个数据字段。默认是空白字符(比如空格或制表符)

使用$1字段变量来显示每行文本的第一个数据字段:

$ cat data2.txt
One line of test text.
Two lines of test text.
Three lines of test text.
$ gawk '{print $1}' data2.txt
One
Two
Three

要读取的文件采用了其他的字段分隔符,可以通过-F选项指定.
将冒号指定为字段分隔符(-F:)来显示了系统中密码文件的第一个数据字段.

$ gawk -F: '{print $1}' /etc/passwd
root
daemon
bin
...
christine
sshd

8.1.2.4.在脚本中使用多条命令

将多条命令组合成一个常规的脚本,在命令之间加入分号.

$ 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

与sed类似,未指定文件时,会从STDIN读取输入,使用Ctrl+D生成EOF来结束脚本.

8.1.2.5.从文件中读取脚本

跟sed编辑器一样,gawk允许将脚本保存在文件中,然后在命令行中引用脚本.

$ cat script2.gawk
{ print $1 "'s home directory is " $6 }
$ gawk -F: -f script2.gawk /etc/passwd
root's home directory is /root
daemon's home directory is /usr/sbin
bin's home directory is /bin
...
sshd's home directory is /run/sshd

可以在脚本文件中指定多条命令。

$ cat script3.gawk
{
text = "'s home directory is "
print $1 text $6
}
$ gawk -F: -f script3.gawk /etc/passwd

在gawk脚本中,引用变量值时无须使用 $ 符号。

8.1.2.6.在处理数据前运行脚本

gawk允许指定脚本何时运行。
默认情况gawk会从输入中读取一行文本,然后对数据执行脚本。有时候需要在处理数据前先运行脚本.

BEGIN关键字会强制gawk在读取数据前执行BEGIN关键字之后指定的脚本.

$ gawk 'BEGIN {print "Hello World!"}'
Hello World!

BEGIN关键字在处理任何数据之前仅应用指定的脚本,在显示过文本后,脚本直接结束,不等待任何数据。

想使用正常的脚本来处理数据,则必须用另一个区域来定义脚本.
在gawk执行了BEGIN脚本后,会用第二段脚本来处理文件数据。
两段脚本仍会被视为gawk命令行中的一个文本字符串,所以需要加在一个单引号内.

$gawk 'BEGIN {print "请每次输入一个单词!"}
> {print $1}'
请每次输入一个单词!
apple red
apple
old new
old
hello world
hello

8.1.2.7.在处理数据后运行脚本

和BEGIN关键字类似,END关键字允许指定一段脚本,gawk会在处理完数据后执行这段脚本

$gawk 'BEGIN {print "请每次输入一个单词!"}
> {print $1}
> END {print "输入结束"}' data3.txt
请每次输入一个单词!
apple red
apple
old new
old
hello world
hello
输入结束

特殊变量FS是定义字段分隔符的另一种方法。无须依靠脚本用户通过命令行选项定义字段分隔符.

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"
}
$ gawk -f script4.gawk /etc/passwd
The latest list of users and shells
UserID           Shell
--------         -------
root             /bin/bash
daemon           /usr/sbin/nologin
...
sshd             /usr/sbin/nologin
This concludes the listing

更多gawk进阶

8.2.sed编辑器基础命令

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

8.2.1.更多的替换选项

8.2.1.1.替换标志

替换命令在替换多行中的文本时使用,默认情况下它只替换每行中出现的第一处匹配文本。

$ cat data4.txt
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.

要想替换每行中所有的匹配文本,必须使用替换标志(substitution flag)。替换标志在替换命令字符串之后设置。

sed 's/pattern/replacement/flags' file

有4种可用的替换标志:

  • 数字,指明新文本将替换行中的第几处匹配。
  • g,指明新文本将替换行中所有的匹配。
  • p,指明打印出替换后的行。
  • w file,将替换的结果写入文件。

数字替换标志,替换指定匹配处:

$ sed 's/test/trial/2' data4.txt
This is a test of the trial script.
This is the second test of the trial script.

g替换标志,替换所有:

$ sed 's/test/trial/g' data4.txt
This is a trial of the trial script.
This is the second trial of the trial script.

p替换标志,打印出包含替换命令中指定匹配模式的文本行。通常和sed的-n选项配合使用.
-n选项会抑制sed编辑器的输出,替换标志p会输出替换后的行。配合使用只输出被替换命令修改过的行。

$ 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.

w替换标志,将替换的结果(仅替换的行)输出保存到指定文件中.
sed编辑器的正常输出会被保存在STDOUT中。

$ 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.

8.2.1.2.替换字符

在字符串中遇到不方便在替换模式中使用的字符。比如正斜线(/)替换文件中的路径会比较烦琐。
由于正斜线被用作替换命令的分隔符,因此它在匹配模式和替换文本中出现时,必须使用反斜线来转义。

如果想将/etc/passwd文件中的bash shell替换为C shell:

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

为了解决这个问题,sed编辑器允许选择其他字符作为替换命令的替代分隔符:

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

以上感叹号(!)被用作替换命令的分隔符.

8.2.2.使用地址

默认情况下,在sed编辑器中使用的命令会应用于所有的文本行。如果只想将命令应用于特定的某一行或某些行,可使用行寻址。

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

  • 以数字形式表示的行区间。
  • 匹配行内文本的模式。

行寻址的格式:

[address]command
# 将针对特定地址的多个命令分组
address {command1command2command3
}

sed编辑器会将指定的各个命令应用于匹配指定地址的文本行。

8.2.2.1.数字形式行寻址

在使用数字形式的行寻址时,可以用行号来引用文本流中的特定行。
sed编辑器会将文本流中的第一行编号为1,第n行编号为n.
在命令中指定的行地址既可以是单个行号,也可以是用起始行号、逗号以及结尾行号指定的行区间。

$可表示最后一行.

$ 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.
$ 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.

8.2.2.2.使用文本模式过滤

sed编辑器允许指定文本模式来过滤出命令所应用的行.
必须将指定的模式(patten)放入正斜线内。sed编辑器会将该命令应用于包含匹配模式的行。

sed '/pattern/command' file
$ 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
...
rich:x:1002:1002::/home/rich:/bin/csh

在文本模式中引入正则表达式来创建匹配效果更好的模式.

8.2.2.3.命令组

在单行中执行多条命令,可以用 {} 组合在一起,sed编辑器会执行匹配地址中列出的所有命令.
可以在一组命令前指定行区间.

$ 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.

8.2.3.删除行(d)

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

删除命令会删除匹配指定模式的所有行。使用该命令时如果忘记加入寻址模式,则流中的所有文本行都会被删除.
同样的,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 'd' data1.txt

从数据流中删除特定的文本行:

  • 通过行号指定:
    $ 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 '2,3d' data6.txt
    This is line number 1.
    This is the 4th line.
    
  • 特殊的末行字符指定:
    $ sed '3,$d' data6.txt
    This is line number 1.
    This is line number 2.
    
  • 模式匹配:
    $ sed '/number 1/d' data6.txt
    This is line number 2.
    This is the 3rd line.
    This is the 4th line.
    
  • 使用两个文本模式来删除某个区间内的行:
    一个模式会“启用”行删除功能,第二个模式会“关闭”行删除功能,sed编辑器会删除包含两个指定行与之间的所有行.
    只要sed编辑器在数据流中匹配到了开始模式,就会启用删除功能.第二个包含开始模式的行也会触发删除命令,未找到结束模式,则剩余的行会被全部删除.
$ cat data7.txt
This is line number 1.
This is line number 2.
This is the 3rd line.
This is the 4th line.
This is line number 1 again; we want to keep it.
This is more text we want to keep.
Last line in the file; we want to keep it.
$ sed '/1/,/3/d' data7.txt
This is the 4th line.

8.2.4.插入和附加文本(a\i)

sed编辑器也可以向数据流中插入和附加文本行。

  • 插入(insert)(i)命令会在指定行前增加一行。
  • 附加(append)(a)命令会在指定行后增加一行。

命令不能在单个命令行中使用。必须指定 插入还是附加 到另一行.

sed '[address]command\
new line' file

插入与附加

$ echo "Test Line 2" | sed 'i\Test Line 1'
Test Line 1
Test Line 2
$ echo "Test Line 2" | sed 'a\Test Line 1'
Test Line 2
Test Line 1
$ echo "Test Line 2" | sed 'i\
> Test Line 1'
Test Line 1
Test Line 2

向数据流内部插入或附加数据,须用地址指定数据出现在什么位置。
只能指定一个行地址。不能用行区间.(只能将文本插入或附加到某一行而不是行区间的前后)

$ 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 '$a\
> This line was added to the end of the file.
> ' data6.txt
This is line number 1.
This is line number 2.
This is the 3rd line.
This is the 4th line.
This line was added to the end of the file.

在数据流的起始位置增加一个新行。只要在第一行之前插入新行。
在数据流的末尾位置增加一个新行。只要在最后一行之后附加新行。

添加多行

要插入或附加多行文本,必须在要插入或附加的每行新文本末尾使用反斜线(\):

$ sed '1i\
> This is an inserted line.\
> This is another inserted line.
> ' data6.txt
This is an inserted line.
This is another inserted line.
This is line number 1.
This is line number 2.
This is the 3rd line.
This is the 4th line.

8.2.5.修改行©

修改(c)命令允许修改数据流中整行文本的内容。必须在sed命令中单独指定一行.

$ 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.
$ sed '/3rd line/c\
> This is a changed line of text.
> ' data6.txt
This is line number 1.
This is line number 2.
This is a changed line of text.
This is the 4th line.

文本模式修改命令会修改所匹配到的任意文本行.

在修改命令中使用地址区间,会将区间内的所有内容替换为一个文本内容,而不会将每一行替换一次.

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

8.2.6.转换命令(y)

转换(y)命令是唯一可以处理单个字符的sed编辑器命令。

sed '[address]y/inchars/outchars/' file

转换命令会对inchars和outchars的字符进行一对一的映射。
inchars中的第一个字符会被转换为outchars中的第一个字符,inchars中的第n字符会被转换成outchars中的第n字符。
如果inchars和outchars的长度不同,sed编辑器会产生错误消息。
转换命令是一个全局命令,会对文本行中匹配到的所有指定字符进行转换,不考虑字符出现的位置,也无法对特定位置字符的转换进行限制:

$ cat data9.txt
This is line 1.
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 5.
This is line 7 again.
This is line 9 again.
This is the last file line.
$ echo "Test #1 of try #1." | sed 'y/123/678/'
Test #6 of try #6.

8.2.7.打印

打印数据流中的信息。

  • 打印(p)命令用于打印文本行。
  • 等号(=)命令用于打印行号。
  • 列出(l)命令用于列出行。

打印行§

和替换命令中的p标志类似,打印命令用于打印sed编辑器输出中的一行。

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

常见的用法是打印包含匹配文本模式的行,通过-n抑制其他行输出:

$ cat data6.txt
This is line number 1.
This is line number 2.
This is the 3rd line.
This is the 4th line.
$ sed -n '/3rd line/p' data6.txt
This is the 3rd line.

在使用替换或修改命令做出改动之前查看相应的行:

$ sed -n '/3/{
> p
> s/line/test/p
> }' data6.txt
This is the 3rd line.
This is the 3rd test.

打印数据流中的部分行:

$ sed -n '2,3p' data6.txt
This is line number 2.
This is the 3rd line.

打印行号(=)

=等号命令会打印文本行在数据流中的行号。行号由数据流中的换行符决定。
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 '=' data1.txt
1
The quick brown fox jumps over the lazy dog.
2
The quick brown fox jumps over the lazy dog.
3
The quick brown fox jumps over the lazy dog.
4
The quick brown fox jumps over the lazy dog.

让sed编辑器只显示包含匹配文本模式的文本行的行号和内容:

$ cat data7.txt
This is line number 1.
This is line number 2.
This is the 3rd line.
This is the 4th line.
This is line number 1 again; we want to keep it.
This is more text we want to keep.
Last line in the file; we want to keep it.
$ sed -n '/text/{
> =
> p
> }' data7.txt
6
This is more text we want to keep.

列出行(l)

列出命令可以打印数据流中的文本和不可打印字符。
在显示不可打印字符的时候,可以使用反斜杠加八进制值,或使用标准的C语言命名规范,比如\t用于代表制表符.

$ cat data10.txt
This    line    contains        tabs.
This line does contain tabs.
$ sed -n 'l' data10.txt
This\tline\tcontains\ttabs.$
This line does contain tabs.$

8.2.8.处理文件

写入文件(w)

命令格式:

sed '[address]w filename' file

filename可以使用相对路径或绝对路径.用户必须有文件的写权限。地址可以是任意类型的寻址方式.

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

可以使用-n选项抑制输出.

根据一些文本值,从主文件(比如下面的邮件列表)中创建一份数据文件,使用写入命令会非常方便:

$ cat data12.txt
Blum, R       Browncoat
McGuiness, A  Alliance
Bresnahan, C  Browncoat
Harken, C     Alliance
$ sed -n '/Browncoat/w Browncoats.txt' data12.txt
$ cat Browncoats.txt
Blum, R       Browncoat
Bresnahan, C  Browncoat

读取数据®

取(r)命令允许将一条独立文件中的数据插入数据流。将文件内容插入指定地址之后.
无法使用地址区间,只能指定单个行号或文本模式地址。
命令格式:

sed '[address]r filename' file
$ cat data13.txt
This is an added line.
This is a second added line.
$ sed '3r data13.txt' data6.txt
This is line number 1.
This is line number 2.
This is the 3rd line.
This is an added line.
This is a second added line.
This is the 4th line.
$ sed '/number 2/r data13.txt' data6.txt
This is line number 1.
This is line number 2.
This is an added line.
This is a second added line.
This is the 3rd line.
This is the 4th line.
$ sed '$r data13.txt' data6.txt
This is line number 1.
This is line number 2.
This is the 3rd line.
This is the 4th line.
This is an added line.
This is a second added line.

读取命令和删除命令配合使用,利用一个文件中的数据来替换另一个文件中的占位文本。
假如你保存在文本文件中的套用信件如下:

$ cat notice.std
Would the following people:
LIST
please report to the ship's captain.

在占位文本后插入名单,只需使用读取命令即可。但这样的话,占位文本仍然会留在输出中。为此,可以用删除命令删除占位文本

$ sed '/LIST/{
> r data12.txt
> d
> }' notice.std
Would the following people:
Blum, R       Browncoat
McGuiness, A  Alliance
Bresnahan, C  Browncoat
Harken, C     Alliance
please report to the ship's captain.

文件夹下文件

-s选项可以告知sed将目录内的各个文件作为单独的流

$ sed -sn '1s!/bin/sh!/bin/bash!' OldScripts/*.sh

将 OldScripts文件夹下的.sh文件第一行内的/bin/sh的替换为/bin/bash.

在这里插入图片描述

相关文章:

【Linux命令行与Shell脚本编程】第十八章 文本处理与编辑器基础

Linux命令行与Shell脚本编程 第十八章 文本处理与编辑器基础 文章目录 Linux命令行与Shell脚本编程第十八章 文本处理与编辑器基础 文本处理与编辑器基础8.1.文本处理8.1.1.sed编辑器8.1.1.1.在命令行中定义编辑器命令8.1.1.2.在命令行中使用多个编辑器命令8.1.1.3.从文件中读…...

2023牛客暑期多校训练营7

Beautiful Sequence 贪心,二进制,构造 Cyperation 模拟 ,数学 We Love Strings 分块,二进制枚举,二进制容斥dp Writing Books 签到 根据相邻两个异或值B,因为前小于等于后,故从高到低遍历B的每一…...

centos7升级glibc2.28

1 概述 centos7自带的glibc对于某些软件是太旧的,决定将glibc升级至2.28。 2 安装过程 2.1 下载glibc源码 mkdir -p /opt/third-party && cd /opt/third-party wget http://ftp.gnu.org/gnu/glibc/glibc-2.28.tar.gz tar -xf glibc-2.28.tar.gz cd glibc…...

腾讯云香港服务器租用_2核2G20M_2核4G30M

腾讯云香港服务器租用费用表,目前中国香港地域轻量应用服务器可选配置2核2G20M、2核2G30M、2核4G30M,操作系统可选Windows和Linux,不只是香港云服务器,新加坡、硅谷、法兰克福和东京服务器均有活动,腾讯云服务器网分享…...

十三、ESP32PS2摇杆(ADC)

1. 运行效果 在上下左右操作PS2摇杆的时候,会检测到数据 2. 滑动电阻...

网络安全的相关知识点

网络安全威胁类型: 1.窃听:广播式网络系统。 2.假冒 3.重放:重复一份报文或者报文的一部分,以便产生一个被授权的效果。 4.流量分析 5.数据完整性破坏 6.拒绝服务 7.资源的非授权使用 8.陷门和特洛伊木马:木马病毒有客…...

算法练习(6):牛客在线编程06 递归/回溯

package jz.bm;import java.io.PushbackInputStream; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays;public class bm6 {/*** BM55 没有重复项数字的全排列*/ArrayList<ArrayList<Integer>> res new ArrayList<>()…...

C#使用OpenCv(OpenCVSharp)图像局部二值化处理实例

本文实例演示C#语言中如何使用OpenCv(OpenCVSharp)对图像进行局部二值化处理。 目录 图像二值化原理 局部二值化 自适应阈值 实例 效果...

MySQL多表关联查询

目录 1. inner join&#xff1a; 2. left join&#xff1a; 3. right join&#xff1a; 4.自连接 5.交叉连接&#xff1a; 6、联合查询 7、子查询 1. inner join&#xff1a; 代表选择的是两个表的交差部分。 内连接就是表间的主键与外键相连&#xff0c;只取得键值一致…...

flutter开发实战-CustomClipper裁剪长图帧动画效果

flutter开发实战-CustomClipper裁剪长图帧动画效果 在开发过程中&#xff0c;经常遇到帧动画的每一帧图显示在超长图上&#xff0c;需要处理这种帧动画效果。我这里使用的是CustomClipper 一、CustomClipper CustomClipper继承于Listenable abstract class CustomClipper e…...

CSS 中的优先级规则是怎样的?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐内联样式&#xff08;Inline Styles&#xff09;⭐ID 选择器&#xff08;ID Selectors&#xff09;⭐类选择器、属性选择器和伪类选择器&#xff08;Class, Attribute, and Pseudo-class Selectors&#xff09;⭐元素选择器和伪元素选择器…...

概率图模型(Probabilistic Graphical Model,PGM)

概率图模型&#xff08;Probabilistic Graphical Model&#xff0c;PGM&#xff09;&#xff0c;是一种用图结构来描述多元随机变量之间条件独立性的概率模型。它可以用来表示复杂的概率分布&#xff0c;进行有效的推理和学习&#xff0c;以及解决各种实际问题&#xff0c;如图…...

Oracle 知识篇+会话级全局临时表在不同连接模式中的表现

标签&#xff1a;会话级临时表、全局临时表、幻读释义&#xff1a;Oracle 全局临时表又叫GTT ★ 结论 ✔ 专用服务器模式&#xff1a;不同应用会话只能访问自己的数据 ✔ 共享服务器模式&#xff1a;不同应用会话只能访问自己的数据 ✔ 数据库驻留连接池模式&#xff1a;不同应…...

MySQL 数据库文件的导入导出

目录 数据库的导出 导出整个数据库 导出数据库中的数据表 导出数据库结构 导出数据库中表的表结构 导出多个数据库 导出所有数据库 数据库的导入 数据库的导出 mysqldump -h IP地址 -P 端口 -u 用户名 -p 数据库名 > 导出的文件名 用管理员权限打开cmd进入MySQL的bi…...

找不到资产文件project.assets.json

NuGet 在“obj”文件夹中写入名为 project.assets.json 的文件&#xff0c;.NET SDK 使用该文件来获取有关要传递到编译器的包的信息 。 如果在生成过程中找不到资产文件 project.assets.json&#xff0c;则会发生此错误。 1.执行命令的方式解决 点击工具&#xff0c;分别展开命…...

【python】python将json字符串导出excel | pandas处理json字符串保存为csv

如何将json转为csv 1、通过json直接转为csv 在Python中&#xff0c;你可以使用pandas库来处理DataFrame&#xff08;数据帧&#xff09;和将JSON数据转换为CSV格式。下面是一个简单的示例代码&#xff0c;展示了如何使用pandas库将JSON数据转换为CSV文件&#xff1a; import p…...

opencv 基础54-利用形状场景算法比较轮廓-cv2.createShapeContextDistanceExtractor()

注意&#xff1a;新版本的opencv 4 已经没有这个函数 cv2.createShapeContextDistanceExtractor() 形状场景算法是一种用于比较轮廓或形状的方法。这种算法通常用于计算两个形状之间的相似性或差异性&#xff0c;以及找到最佳的匹配方式。 下面是一种基本的比较轮廓的流程&…...

分布式系统理论

以前的架构...

Gartner发布2023年的存储技术成熟曲线

技术路线说明 Gartner自1995年起开始采用技术成熟度曲线&#xff0c;它描述创新的典型发展过程&#xff0c;即从过热期发展到幻灭低谷期&#xff0c;再到人们最终理解创新在市场或领域内的意义和角色。 一项技术 (或相关创新)在发展到最终成熟期的过程中经历多个阶段&#xff1…...

c++ 有元

友元分为两部分内容 友元函数友元类 友元函数 问题&#xff1a;当我们尝试去重载operator<<&#xff0c;然后发现没办法将operator<<重载成成员函数。因为cout的输出流对象和隐含的this指针在抢占第一个参数的位置。this指针默认是第一个参数也就是左操作 数了。…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用

一、方案背景​ 在现代生产与生活场景中&#xff0c;如工厂高危作业区、医院手术室、公共场景等&#xff0c;人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式&#xff0c;存在效率低、覆盖面不足、判断主观性强等问题&#xff0c;难以满足对人员打手机行为精…...

轻量级Docker管理工具Docker Switchboard

简介 什么是 Docker Switchboard &#xff1f; Docker Switchboard 是一个轻量级的 Web 应用程序&#xff0c;用于管理 Docker 容器。它提供了一个干净、用户友好的界面来启动、停止和监控主机上运行的容器&#xff0c;使其成为本地开发、家庭实验室或小型服务器设置的理想选择…...