这无需预先计算文件中的行数即可工作:
sed -ni '1{p;b}; 2{N;N;N;N}; $p; $!{N;s/^/word /;P;D}' filename
这缓冲了五行并在缓冲区中的第一行进行替换并打印并删除它。当读取文件中的最后一行时,将打印缓冲区而不进行任何替换。
1{p;b}
- 读取第一行,原样打印并分支到最后
2{N;N;N;N}
- 读取第 2 行时,再追加 4 行以创建一个 5 行缓冲区
$p
- 当文件的最后一行被读取时,打印保留在缓冲区中的行不变
$!
- 当当前行不是文件的最后一行时...
N
- 将下一行附加到缓冲区(模式空间)
s/^/word /
- 在缓冲区的第一行进行替换
P
- 仅打印缓冲区中的第一行
D
- 仅删除缓冲区中的第一行
请注意,这不适用于包含少于 6 行的文件。
这与使用 AWK 的想法相同:
awk 'FNR == 1 {print; next} FNR == 2 {for (ptr = 0; ptr <= 4; ptr++) {buffer[ptr] = $0; getline}; ptr = 0} {sub(/^/, "word ", buffer[ptr]); print buffer[ptr]; buffer[ptr] = $0; ptr = (ptr + 1) % 5} END {for (i = 0; i <= 4; i++) {print buffer[(ptr + i) % 5]}}' filename > outputfile
mv outputfile filename
这里分为多行:
FNR == 1 {
print
next
}
FNR == 2 {
for (ptr = 0; ptr <= 4; ptr++) {
buffer[ptr] = $0
getline
}
ptr = 0
}
{
sub(/^/, "word ", buffer[ptr])
print buffer[ptr]
buffer[ptr] = $0
ptr = (ptr + 1) % 5
}
END {
for (i = 0; i <= 4; i++) {
print buffer[(ptr + i) % 5]
}
}