Perl
perl -ne 'print if $.%3==1;$var=$_ if $.%3==2;print $_ . $var if $.%3==0' input.txt
ここでの考え方は、%
行番号$.
変数を使用してモジュロ演算子を使用し、1つおき、1つおき、および3行おきに計算することです。3行目ごとに残りは0ですが、1行目と2行目ごとに対応する番号があります。
テスト:
$ cat input.txt
gi_1234
My cat is blue.
I have a cat.
gi_5678
My dog is orange.
I also have a dog.
$ perl -ne 'print if $.%3==1;$var=$_ if $.%3==2;print $_ . $var if $.%3==0' input.txt
gi_1234
I have a cat.
My cat is blue.
gi_5678
I also have a dog.
My dog is orange.
軽微な改善
2行目を変数に格納するアプローチには欠点があります。最後の行が「2番目」である場合、つまりその行番号の残りが2の場合はどうなりますか?私とDopeGhotiの回答の元のコードはMy dog is orange
、最後の行を省略すると印刷されません。どちらの場合も、修正END{}
後は、コードブロックを使用して、印刷後に一時変数の設定を解除します。言い換えると:
$ awk 'NR%3 == 1 { print } NR%3 == 2 { delay=$0 } NR%3 == 0 { print; print delay;delay=""}END{print delay}' input.txt
そして
$ perl -ne '$s=$_ if $.%3==2;print $_ . $s and $s="" if $.%3==0 or $.%3==1;END{print $s}' input.txt
このようにして、コードは3で割り切れる行だけでなく、ファイル内の任意の行数で機能します。
コメントに記載されている問題の追加修正
awkの場合、ファイルの最終行が$に対して1の出力を生成する場合。%3、前のコードは、理由の無条件の印刷の空白改行を出力する問題を持ってEND{print delay}
いるので、print
コメントに記載された機能は、常にそれが動作しているものは何でも変数に改行を追加します。perl
バージョンの場合、-ne
フラグprint
機能では改行が追加されないため、この問題は発生しません。
それにもかかわらず、コメントでDope Ghotiが言及したように、awkの場合の修正は一時的な変数の長さを確認することです。同じ修正のperlバージョンは次のようになります。
$ perl -ne '$s=$_ if $.%3==2;print $_ . $s and $s="" if $.%3==0 or $.%3==1;END{print $s if length $s}' input.txt