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

news2024/11/15 15:51:26

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 {
    command1
    command2
    command3
}

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.

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/855665.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

项目8.9总结

这两天写了评论和用户之间的关注,然后就是歌曲的上传,歌曲的上传很简陋,并且还有点问题 关注 歌曲上传

[Vue] Vue2和Vue3的生命周期函数

vue2有11个生命周期钩子, vue3有8个生命周期钩子 从vue创建、运行、到销毁总是伴随着各种事件, 创建、挂载、更新到销毁。 1.vue2系列生命周期 ⑴【beforecreate】实例创建前。 vue完全创建之前,会自动执行这个函数。 ⑵【Created】实例创建后。 这也是个生命…

OKHTTP缓存问题记录

使用okhttp的缓存功能 okhttp有一个功能就是适配http协议里面cache-control头 但是在实际使用的过程中,发现非文本内容,如果不对Response中的inputstream读取,就不会缓存下来 比如使用如下代码读取后才能缓存到cache目录 ResponseBody bod…

冷链冷藏仓储系统解决方案|海格里斯HEGERLS四向穿梭立体库助力冷链物流新模式

随着现代物流产业的迅速发展,四向穿梭车立体库因其在仓储体系中所具有的高效密集存储功能优势、运作成本优势与系统化智能化管理优势,已经成为自动化立体库的主流形式之一。而随着国内外仓储物流整体规模和低温产品消费需求的稳步增长,冷链市…

关于使用pycharm遇到只能使用unittest方式运行,无法直接选择Run

相信大家可能都遇到过这个问题,使用pycharm直接运行脚本的时候,只能选择unittest的方式,能愁死个人 经过几次各种尝试无果之后,博主就放弃死磕了,原谅博主是个菜鸟 后来遇到这样的问题,往往也就直接使用cm…

【ChatGPT 指令大全】销售怎么借力ChatGPT提高效率

目录 销售演说 电话销售 产出潜在客户清单 销售领域计划 销售培训计划 总结 随着人工智能技术的不断进步,我们现在有机会利用ChatGPT这样的智能助手来改进我们的销售工作。在接下来的时间里,我将为大家介绍如何运用ChatGPT提高销售效率并取得更好的…

SuperMap GIS基础产品WebGIS FAQ集锦(5)

SuperMap GIS基础产品WebGIS FAQ集锦(5) 【iClient】iClient for Classic如何设置服务跨域时,请求json而不是jsonp? 【解决办法】可全局修改SuperMap.Util.isInTheSameDomain方法,使其返回为true;例如&…

UGUI组件EventTrigger用法

一.Unity编辑器中EventTrigger组件用法 1.添加事件类型 2.绑定gameObject指定组件的方法 3.方法执行逻辑 public class NewBehaviourScript : MonoBehaviour {public void PointerDown(){Debug.Log("Trigger PointerDown");} } 4.按下鼠标,绑定方法成功…

一文了解Java序列化和反序列化:对象的存储与传输

一文了解Java序列化和反序列化:对象的存储与传输 作者:Stevedash 发布时间:2023年8月9日 21点30分 前言 Java序列化是一项强大而重要的技术,它允许我们将对象转换为字节流,以便在存储、传输和重建时使用。在本文中&…

python爬虫相关

目录 初识爬虫 爬虫分类 网络爬虫原理 爬虫基本工作流程 搜索引擎获取新网站的url robots.txt HTHP协议 Resquests模块 前言: 安装 普通请求 会话请求 response的常用方法 简单案例 aiohttp模块 使用前安装模块 具体案例 数据解析 re解析 bs4…

Appium2 安装步骤

自 2022 年 1 月 1 日起,Appium 不再维护 Appium 1.x,官方支持的平台驱动程序的所有最新版本均不兼容 Appium 1.x,需要 Appium 2 才能运行。开启了全新的Appium 2.0之旅。可通过官方文档查看Appium2 移除的功能和新增的功能。 第一步、安装 …

io_uring笔记

目录 io_uring 异步io_uring 使用对比于epoll的效果io_uring效果好在哪? io_uring 异步 要求内核linux 5.10 异步四元组:1、init(create)2、commit 3、callback 4、destory fio : 测iops一秒钟读写磁盘的次数 方式磁盘iopsio_ur…

TCPDF生成PDF文件,含jpjraph生成雷达图

TCPDF生成PDF文件,含jpjraph生成雷达图 依赖自行安装 "tecnickcom/tcpdf": "^6.6","amenadiel/jpgraph": "4"雷达图生成 中文字体添加安装 没有封装,只作为测试案例展示 // 创建新的PDF文档$pdf new \TCPD…

throw和throws的区别

在Java中,throw和throws是两个关键字,用于异常处理。它们具有以下区别: 1. throw关键字: - throw关键字用于主动抛出异常。当程序执行到throw语句时,会创建一个异常对象并将其抛出。 - throw语句通常在方法内部…

fastadmin、vue、react图标库适用于多种框架

在二开fastadmin中,在写vue以及react时,侧边导航栏以及按钮中常常需要很多图标,那么这些图标应该去哪里得到呢,在这里给大家一个链接,这里有丰富的图标库,可以找到自己想要的进行使用。 点击下方链接&…

(树) 剑指 Offer 34. 二叉树中和为某一值的路径 ——【Leetcode每日一题】

❓ 剑指 Offer 34. 二叉树中和为某一值的路径 难度:中等 给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例 1: 输入&#xff1a…

opencv 基础50-图像轮廓学习03-Hu矩函数介绍及示例-cv2.HuMoments()

什么是Hu 矩? Hu 矩(Hu Moments)是由计算机视觉领域的科学家Ming-Kuei Hu于1962年提出的一种图像特征描述方法。这些矩是用于描述图像形状和几何特征的不变特征,具有平移、旋转和尺度不变性,适用于图像识别、匹配和形状…

微信小程序 地图map(电子围栏圆形和多边形)

正常情况下是没有手机上画电子围栏的,公共平台上我也没找到,所以走了一个歪点子,就是给地图添加点击事件,记录点的位置,在画到电子围栏上就是添加电子围栏了,如果只是显示电子围栏就简单了 一、多边形电子…

kubernetes中的kubectl命令详解

kubectl命令详解 一:陈述式资源管理方法:(1)简单的基础命令1.查看版本信息2.查看资源对象简写3.查看集群信息4.配置kubectl自动补全5.node节点查看日志 (2)基本信息查看1.查看 master 节点状态2.查看命名空…

黑马大数据学习笔记4-Hive部署和基本操作

目录 思考规划安装MySQL数据库修改root用户密码配置Hadoop下载解压Hive提供MySQL Driver包配置Hive初始化元数据库启动Hive(使用Hadoop用户)Hive体验HiveServer2HiveServer2服务启动 Beeline p48、51、52 https://www.bilibili.com/video/BV1WY4y197g7/?…