これは、ファイル内の行数を事前に数えなくても機能します。
sed -ni '1{p;b}; 2{N;N;N;N}; $p; $!{N;s/^/word /;P;D}' filename
これは 5 行をバッファリングし、バッファの最初の行で置換を行い、出力して削除します。ファイルの最後の行が読み取られると、バッファーは置換を行わずに出力されます。
- 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]
    }
}