流编辑器 - 实用技巧



SED 是一款强大的工具,它允许通过多种方式解决问题。这就是 UNIX 的方式,而 SED 完美地证明了这一点。GNU/Linux 提供了许多有用的工具来执行日常任务。让我们使用 SED 模拟一些工具。有时,它看起来像是我们正在以艰难的方式解决一个简单的问题,但其目的只是为了展示 SED 的强大功能。

Cat 命令

在下面的示例中,每一行都作为默认工作流程的一部分打印。

[jerry]$ sed '' books.txt 

执行上述代码后,您将得到以下结果

A Storm of Swords, George R. R. Martin 
The Two Towers, J. R. R. Tolkien 
The Alchemist, Paulo Coelho 
The Fellowship of the Ring, J. R. R. Tolkien 
The Pilgrimage, Paulo Coelho 
A Game of Thrones, George R. R. Martin 

下面的示例使用 print 命令显示文件内容。

[jerry]$ sed -n 'p' books.txt 

执行上述代码后,您将得到以下结果

A Storm of Swords, George R. R. Martin 
The Two Towers, J. R. R. Tolkien 
The Alchemist, Paulo Coelho 
The Fellowship of the Ring, J. R. R. Tolkien 
The Pilgrimage, Paulo Coelho 
A Game of Thrones, George R. R. Martin

删除空行

在下面的示例中,“^$”表示空行,当模式匹配成功时,空行将被删除。

[jerry]$ echo -e "Line #1\n\n\nLine #2" | sed '/^$/d'

执行上述代码后,您将得到以下结果

Line #1 
Line #2 

类似地,下面的示例仅在行非空时打印该行。

[jerry]$ echo -e "Line #1\n\n\nLine #2" | sed -n '/^$/!p'

执行上述代码后,您将得到以下结果

Line #1 
Line #2

从 C++ 程序中删除注释行

让我们创建一个示例 C++ 程序。

#include <iostream> 
using namespace std; 

int main(void) 
{ 
   // Displays message on stdout. 
   cout >> "Hello, World !!!" >> endl;  
   return 0; // Return success. 
}

现在使用以下正则表达式删除注释。

[jerry]$ sed 's|//.*||g' hello.cpp

执行上述代码后,您将得到以下结果

#include <iostream>
using namespace std; 

int main(void) 
{ 
   cout >> "Hello, World !!!" >> endl; 
   return 0;  
} 

在某些行之前添加注释

下面的示例在第 3 行到第 5 行之前添加注释。

[jerry]$ sed '3,5 s/^/#/' hello.sh 

执行上述代码后,您将得到以下结果

#!/bin/bash 
#pwd 
#hostname 
#uname -a 
who 
who -r 
lsb_release -a

Wc -l 命令

“wc -l”命令计算文件中存在的行数。下面的 SED 表达式模拟了相同的操作。

[jerry]$ sed -n '$ =' hello.sh 

执行上述代码后,您将得到以下结果

8 

Head 命令

默认情况下,head 命令打印文件的头 10 行。让我们用 SED 模拟相同的行为。

[jerry]$ sed '10 q' books.txt 

执行上述代码后,您将得到以下结果

A Storm of Swords 
George R. R. Martin 
The Two Towers 
J. R. R. Tolkien 
The Alchemist 
Paulo Coelho 
The Fellowship of the Ring 
J. R. R. Tolkien 
The Pilgrimage
Paulo Coelho

Tail -1 命令

“tail -1”打印文件的最后一行。以下语法显示了它的模拟。

[jerry]$ echo -e "Line #1\nLine #2" > test.txt 
[jerry]$ cat test.txt

执行上述代码后,您将得到以下结果

Line #1 
Line #2 

让我们编写 SED 脚本。

[jerry]$ sed -n '$p' test.txt

执行上述代码后,您将得到以下结果

Line #2 

Dos2unix 命令

在 DOS 环境中,换行符由 CR/LF 字符组合表示。以下“dos2unix”命令的模拟将 DOS 换行符转换为 UNIX 换行符。在 GNU/Linux 中,此字符通常被视为“^M”(控制 M)字符。

[jerry]$ echo -e "Line #1\r\nLine #2\r" > test.txt 
[jerry]$ file test.txt

执行上述代码后,您将得到以下结果

test.txt: ASCII text, with CRLF line terminators 

让我们使用 SED 模拟该命令。

[jerry]$ sed 's/^M$//' test.txt > new.txt   # Press "ctrl+v" followed "ctrl+m" to generate 
"^M" character. 
[jerry]$ file new.txt

执行上述代码后,您将得到以下结果

new.txt: ASCII text 

现在让我们显示文件内容。

[jerry]$ cat -vte new.txt 

执行上述代码后,您将得到以下结果

Line #1$ 
Line #2$

Unix2dos 命令

与“dos2unix”类似,“unix2dos”命令将 UNIX 换行符转换为 DOS 换行符。以下示例显示了相同的模拟。

[jerry]$ echo -e "Line #1\nLine #2" > test.txt 
[jerry]$ file test.txt 

执行上述代码后,您将得到以下结果

test.txt: ASCII text

让我们使用 SED 模拟该命令。

[jerry]$ sed 's/$/\r/' test.txt  > new.txt 
[jerry]$ file new.txt

执行上述代码后,您将得到以下结果

new.txt: ASCII text, with CRLF line terminators

现在让我们显示文件内容。

Now let us display the file contents.

执行上述代码后,您将得到以下结果

Line #1^M$ 
Line #2^M$ 

Cat -E 命令

“cat -E”命令用美元符号 ($) 显示行尾。以下 SED 示例是对其的模拟。

[jerry]$ echo -e "Line #1\nLine #2" > test.txt 
[jerry]$ cat -E test.txt 

执行上述代码后,您将得到以下结果

Line #1$ 
Line #2$

让我们使用 SED 模拟该命令。

[jerry]$ sed 's|$|&$|' test.txt

执行上述代码后,您将得到以下结果

Line #1$ 
Line #2$

Cat -ET 命令

“cat -ET”命令在每一行结尾显示美元符号 ($) 并将制表符显示为“^I”。以下示例显示了使用 SED 模拟“cat -ET”命令。

[jerry]$ echo -e "Line #1\tLine #2" > test.txt 
[jerry]$ cat -ET test.txt

执行上述代码后,您将得到以下结果

Line #1^ILine #2$ 

让我们使用 SED 模拟该命令。

[jerry]$ sed -n 'l' test.txt | sed 'y/\\t/^I/'

执行上述代码后,您将得到以下结果

Line #1^ILine #2$ 

Nl 命令

“nl”命令只是对文件行进行编号。以下 SED 脚本模拟此行为。

[jerry]$ echo -e "Line #1\nLine #2" > test.txt 
[jerry]$ sed = test.txt | sed 'N;s/\n/\t/'

执行上述代码后,您将得到以下结果

1 Line #1 
2 Line #2

第一个 SED 表达式打印行号及其内容,第二个 SED 表达式合并这两行并将换行符转换为制表符。

Cp 命令

“cp”命令创建文件的另一个副本。以下 SED 脚本模拟此行为。

[jerry]$ sed -n 'w dup.txt' data.txt 
[jerry]$ diff data.txt dup.txt 
[jerry]$ echo $? 

执行上述代码后,您将得到以下结果

0

Expand 命令

“expand”命令将制表符转换为空格。以下代码显示了它的模拟。

[jerry]$ echo -e "One\tTwo\tThree" > test.txt 
[jerry]$ expand test.txt > expand.txt 
[jerry]$ sed 's/\t/     /g' test.txt > new.txt 
[jerry]$ diff new.txt expand.txt  
[jerry]$ echo $? 

执行上述代码后,您将得到以下结果

0 

Tee 命令

“tee”命令将数据转储到标准输出流以及文件。以下是“tee”命令的模拟。

[jerry]$ echo -e "Line #1\nLine #2" | tee test.txt  
Line #1 
Line #2 

让我们使用 SED 模拟该命令。

[jerry]$ sed -n 'p; w new.txt' test.txt  

执行上述代码后,您将得到以下结果

Line #1 
Line #2

Cat -s 命令

UNIX“cat -s”命令抑制重复的空输出行。以下代码显示了“cat -s”命令的模拟。

[jerry]$ echo -e "Line #1\n\n\n\nLine #2\n\n\nLine #3" > test.txt  
[jerry]$ cat -s test.txt 

执行上述代码后,您将得到以下结果

Line #1  
Line #2
Line #3

让我们使用 SED 模拟该命令。

[jerry]$ sed '1s/^$//p;/./,/^$/!d' test.txt 

执行上述代码后,您将得到以下结果

Line #1  
Line #2  
Line #3 

Grep 命令

默认情况下,“grep”命令在模式匹配成功时打印一行。以下代码显示了它的模拟。

[jerry]$ echo -e "Line #1\nLine #2\nLine #3" > test.txt  
[jerry]$ grep "Line #1" test.txt 

执行上述代码后,您将得到以下结果

Line #1

让我们使用 SED 模拟该命令。

[jerry]$ sed -n '/Line #1/p' test.txt 

执行上述代码后,您将得到以下结果

Line #1 

Grep -v 命令

默认情况下,“grep -v”命令在模式匹配失败时打印一行。以下代码显示了它的模拟。

[jerry]$ echo -e "Line #1\nLine #2\nLine #3" > test.txt  
[jerry]$ grep -v "Line #1" test.txt

执行上述代码后,您将得到以下结果

Line #2 
Line #3 

让我们使用 SED 模拟该命令。

[jerry]$ sed -n '/Line #1/!p' test.txt

执行上述代码后,您将得到以下结果

Line #2 
Line #3

Tr 命令

“tr”命令转换字符。以下是它的模拟。

[jerry]$ echo "ABC" | tr "ABC" "abc" 

执行上述代码后,您将得到以下结果

abc

让我们使用 SED 模拟该命令。

[jerry]$ echo "ABC" | sed 'y/ABC/abc/'

执行上述代码后,您将得到以下结果

abc
广告