Perl
perl -ne 'print if $.%3==1;$var=$_ if $.%3==2;print $_ . $var if $.%3==0' input.txt
Ý tưởng ở đây là chúng ta sử dụng toán tử modulo %
với $.
biến số dòng , để tìm ra cái nào là đầu tiên, cái nào là mỗi giây và cái nào là dòng thứ 3. Với mỗi dòng thứ 3 còn lại là 0, trong khi với mỗi dòng thứ 1 và thứ 2, nó sẽ có các số tương ứng.
Kiểm tra:
$ 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.
Cải thiện nhỏ
Cách tiếp cận với việc lưu trữ dòng thứ hai vào một biến có một lỗ hổng. Điều gì sẽ xảy ra nếu dòng cuối cùng là dòng "thứ hai", tức là phần còn lại của số dòng đó là 2? Mã ban đầu trong câu trả lời của tôi và DopeGhoti sẽ không được in My dog is orange
nếu chúng tôi rời khỏi dòng cuối cùng. Cách khắc phục trong cả hai trường hợp là sử dụng END{}
khối mã, với việc bỏ đặt biến tạm thời sau khi in. Nói cách khác:
$ awk 'NR%3 == 1 { print } NR%3 == 2 { delay=$0 } NR%3 == 0 { print; print delay;delay=""}END{print delay}' input.txt
và
$ perl -ne '$s=$_ if $.%3==2;print $_ . $s and $s="" if $.%3==0 or $.%3==1;END{print $s}' input.txt
Theo cách này, mã sẽ hoạt động với số lượng dòng tùy ý trong một tệp, không chỉ các dòng chia hết cho 3.
Sửa chữa bổ sung cho vấn đề được đề cập trong ý kiến
Trong trường hợp của awk, nếu dòng cuối cùng trong tệp tạo ra đầu ra là 1 cho $. % 3, mã trước có vấn đề xuất ra dòng mới trống vì in vô điều kiện END{print delay}
, vì print
chức năng được đề cập trong các nhận xét luôn nối thêm dòng mới vào bất kỳ biến nào mà nó đang hoạt động. Trong trường hợp perl
phiên bản, sự cố này không xảy ra, vì chức năng -ne
cờ print
không nối thêm dòng mới.
Tuy nhiên, cách khắc phục trong trường hợp của awk là tạo điều kiện, như Dope Ghoti đã đề cập trong các bình luận là để xác minh độ dài của biến tạm thời. Phiên bản perl của cùng một bản sửa lỗi sẽ là:
$ perl -ne '$s=$_ if $.%3==2;print $_ . $s and $s="" if $.%3==0 or $.%3==1;END{print $s if length $s}' input.txt