保持缓冲区在sed允许您临时存储和检索输入行。
将其视为辅助存储器,您可以在使用主模式空间时放置数据。
当您需要一次执行涉及多行的操作时,保持缓冲区特别有用。
保留缓冲区不是立即处理和打印每一行,而是让您保存一行、处理其他行,然后在需要时返回保存的行。
模式空间和保持空间之间的区别
In sed
,在处理输入时,您将主要处理两个主要缓冲区:模式空间和保持空间。
模式空间:这是默认的工作空间sed
。每当sed
从输入中读取一行,并将该行放入模式空间中。
在这里,所有编辑命令都作用于该空间的内容。处理完特定行的所有命令后,sed
通常输出模式空间内容,然后清除它以在下一行输入中读取。
echo -e "apple\norange" | sed 's/apple/fruit/'
Output:
fruit
orange
在上面的命令中,sed
在打印结果之前,在模式空间中将“apple”替换为“fruit”。
保持空间:保留空间用作临时存储,可以与模式空间结合使用。
虽然模式空间不断地被每行新的输入覆盖,但保留空间仍然保持不变,直到显式修改为止。
这允许您保存一行或任何数据,以便稍后在您的sed
加工。
echo -e "apple\norange" | sed -n '1h; 2{g; p;}'
Output:
apple
在此示例中,第一行“apple”被复制到保留空间1h
.
在第二行,2{g; p;}
从保留空间获取内容并将其放入模式空间,然后打印它。
由于保留空间有“apple”,所以这就是打印的内容。
图案空间和存放空间都提供不同的功能。虽然模式空间允许立即处理,但保持空间非常适合跨多行保存数据。
将模式空间复制到保持缓冲区
The h
命令输入sed
将模式空间的内容复制到保持缓冲区中。
当您使用此命令时,此时模式空间中的任何内容都会存储在保持缓冲区中,替换以前保存在那里的任何内容。
让我们通过一个实际的例子来证明这一点:
echo -e "apple\norange\nbanana" | sed -n '1h; 2p; 3g; 3p'
Output:
orange
apple
以下是逐步发生的情况:
- 对于第一行“apple”,
1h
命令将其复制到保持缓冲区中。
- 对于第二行“orange”,
2p
命令打印它。
- 对于第三行“banana”,
3g
命令从保持缓冲区获取内容并将其放置在模式空间中。由于“apple”存储在保持缓冲区中,因此模式空间现在包含“apple”。
- 仍然在第三行,
3p
命令打印模式空间的当前内容,即“apple”。
将模式空间附加到保持缓冲区
The H
命令输入sed
允许您将模式空间的内容附加到保持缓冲区。
它不会替换保持缓冲区的现有内容。
相反,它将模式空间内容附加到保持缓冲区中已有的内容之后,并且这两部分数据由新行分隔。
下面是一个示例来阐明此操作:
echo -e "apple\norange" | sed -n '1h; 2H; 2g; 2p'
Output:
apple
orange
分解步骤:
- 第一行“apple”,
1h
命令将其复制到保持缓冲区。
- 在第二行“橙色”中,
2H
命令将此行附加到保持缓冲区。此时,保持缓冲区包含“apple\norange”。
- 仍然在第二行,
2g
命令从保持缓冲区获取全部内容并将其放置在模式空间中。
- 最后,
2p
命令打印模式空间的内容,结果是两行:“apple”和“orange”。
用保持缓冲区内容替换模式空间
The g
命令输入sed
用于将模式空间的内容替换为保持缓冲区中的内容。
当您希望从保持缓冲区检索以前存储的数据并在模式空间内对其进行操作时,这是一个方便的命令。
让我们深入研究一个例子:
echo -e "apple\norange" | sed -n '1h; 2g; 2p'
Output:
apple
了解流程:
- 第一行“apple”,
1h
命令将此内容移动到保持缓冲区中。
- 当处理第二行“orange”时,
2g
命令用保持缓冲区的内容(“apple”)替换模式空间的内容(“orange”)。
- 紧接着,
2p
命令打印模式空间的内容,现在是“apple”。
将保持缓冲区附加到模式空间
The G
命令输入sed
用于将保持缓冲区的内容附加到模式空间,并以换行符分隔。
让我们通过一个例子来理解这个概念:
echo -e "apple\norange" | sed -n '1h; 2G; 2p'
Output:
orange
apple
分步演练:
- 对于“苹果”系列,
1h
命令将其内容存入保持缓冲区。
- 当我们处理第二行“orange”时,
2G
命令将保留缓冲区的内容(即“apple”)附加到模式空间,确保它们由换行符分隔。然后模式空间保存“orange\napple”。
- 随后的
2p
命令打印模式空间的串联内容。
交换保持缓冲区和模式空间
The x
命令输入sed
用于交换模式空间和保持缓冲区的内容。
让我们深入研究一个例子:
echo -e "apple\norange" | sed -n '1h; 2x; 2p'
Output:
apple
发生的情况如下:
- 在“apple”这一行,我们使用
1h
命令将其内容存储到保持缓冲区中。
- 当我们到达第二行“橙色”时,
2x
命令将模式空间(“orange”)的内容与保持缓冲区(“apple”)的内容交换。交换后,模式空间包含“apple”,保持缓冲区包含“orange”。
- 交换之后,立即
2p
命令打印模式空间的当前内容,即“apple”。
保持缓冲区的用例
保持缓冲区在sed
不仅仅是一个存储空间;它是一种为执行多行处理打开大门的机制。让我们探讨一下保持缓冲区的一些关键用例:
保存和检索多行处理的行
您可以存储一行(或多行),然后使用保存的数据对后续行应用操作。
echo -e "header\ncontent\nfooter" | sed -n '/header/h; /footer/{g; p;}'
Output:
header
在这种情况下,“标题”行被保存到保持缓冲区。当我们遇到“页脚”行时,我们检索“页眉”并打印它。
存储行之间的上下文或状态
有时,在处理后面的行时,您需要回忆上下文或特定状态。保持缓冲区可以充当存储器,让您可以参考先前的行以获取上下文。
echo -e "apple\norange\ninfo: banana" | sed -n '/apple/h; /info:/{x;G; s/info: //; p;}'
Output:
apple
banana
-
/apple/h
:将包含“apple”的行复制到保持缓冲区。
-
/info:/
:查找包含“info:”的行。
-
{x; ...}
:对于这些行,交换保持缓冲区和模式空间,这会将“apple”放入模式空间并将“info:banana”放入保持缓冲区。
-
G
:将保持缓冲区(现在包含“info:banana”)附加到模式空间。
-
s/info: //
:删除“info:”前缀。
-
p
:打印图案空间。
重新排列行或块的顺序
保持缓冲区的更高级用途之一是对文本行或文本块重新排序。
如果您需要根据条件或模式对数据序列进行打乱,则保持缓冲区将成为不可或缺的工具。
echo -e "line2\nline1" | sed -n '1h; 2{p; x; p;}'
Output:
line1
line2
-
1h
:在第一行(line2
),将内容复制到保持缓冲区。
-
2{p; x; p;}
: On the second line:
-
p
:打印当前模式空间(line1
).
-
x
:与保持缓冲区交换模式空间,这带来了line2
进入模式空间。
-
p
:打印现在包含的模式空间line2
.
使用保持缓冲区进行多遍编辑
假设您有一个文本块需要一系列不同的转换。
试图在一次传递中实现这一点将是复杂且容易出错的。多遍编辑允许您:
- 将转换分解为孤立的步骤。
- 在进行下一个转换之前确保每个转换的准确性。
- 安全存储中间结果以供后续处理。
让我们深入研究一个我们想要的示例:
- 将水果列表转换为大写。
- 在每个水果前加上“FRUIT:”一词。
Command:
echo -e "apple\norange\nbanana" | sed -n -e '1,3{s/.*/\U&/;h}' -e '1,3{x;s/^/FRUIT: /;p}'
Output:
FRUIT: APPLE
FRUIT: ORANGE
FRUIT: BANANA
分解步骤:
First -e
(前三行的第一遍):
1,3{s/.*/\U&/;h}
:对于第1行到第3行,我们将整行转换为大写,然后将其存储在保持缓冲区中。
Second -e
(前三行的第二遍):
1,3{x;s/^/FRUIT: /;p}
:对于第 1 行到第 3 行,我们将保持缓冲区的内容与模式空间交换,并在该行前面添加“FRUIT:”前缀,然后打印它。
使用复杂脚本管理保持缓冲区
在处理复杂的脚本时,尤其是那些密集利用保持缓冲区的脚本时,有效管理保持缓冲区以防止意外结果并保持可读性至关重要。
必要时清除保持缓冲区
有时不再需要保留缓冲区的内容,为了防止意外使用它,您可能需要清除它。
要清除保持缓冲区:
s/.*//
h
这可以确保您从头开始,特别是在缓冲区的内容可能干扰后续操作的情况下。
使用保持缓冲区进行调试
调试一个sed
脚本,尤其是涉及保持缓冲区的脚本,可能具有挑战性。一种方法是在战略点打印图案空间和保持缓冲区。
用这个:
# Print pattern space and hold buffer for debugging
l0
g
l0
这将提供两个缓冲区的清晰视图,帮助您跟踪脚本中的数据流。