Perl
perl -ne 'print if $.%3==1;$var=$_ if $.%3==2;print $_ . $var if $.%3==0' input.txt
Buradaki fikir , hangisinin ilk önce hangisinin, hangisinin saniyede ve hangisinin 3. satırda olduğunu anlamak için %
satır numarası $.
değişkenli modulo operatörü kullanmamızdır . Kalan her 3. satır için 0, her 1. ve 2. satır için karşılık gelen sayılar olacaktır.
Ölçek:
$ 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.
Küçük gelişme
İkinci satırı değişkene kaydetme yaklaşımının bir kusuru vardır. Son satır "ikinci" ise, yani kalan satır sayısı için 2 olursa ne olur? Son satırdan çıkarsak, benim ve DopeGhoti'nin cevabındaki orijinal kod yazdırılmaz My dog is orange
. Her iki durumda da düzeltme END{}
, yazdırma sonrasında geçici değişkenin ayarının kaldırılmasıyla kod bloğunu kullanmaktır . Başka bir deyişle:
$ awk 'NR%3 == 1 { print } NR%3 == 2 { delay=$0 } NR%3 == 0 { print; print delay;delay=""}END{print delay}' input.txt
ve
$ perl -ne '$s=$_ if $.%3==2;print $_ . $s and $s="" if $.%3==0 or $.%3==1;END{print $s}' input.txt
Bu şekilde, kod bir dosyadaki rasgele sayıda satır için çalışır, sadece 3 ile bölünebilir olanlar için değil.
Yorumlarda bahsedilen sorun için ek düzeltme
Awk durumunda, dosyadaki son satır $ için 1 çıktısı üretirse. % 3, önceki kod yüzünden koşulsuz baskı boş bir yeni satır için çıktı alma sorunu var END{print delay}
çünkü, print
yorum olarak bahsedilen fonksiyon her zaman üzerinde çalıştığı herhangi bir değişkeni için yeni satırı ekler. perl
Sürüm durumunda, -ne
bayraklar print
işlevi yeni satırı eklemediği için bu sorun oluşmaz .
Bununla birlikte, awk'ın durumundaki düzeltme, Dope Ghoti tarafından yorumlarda belirtildiği gibi koşullu yapmaktır, geçici değişkenin uzunluğunu doğrulamaktır. Aynı düzeltmenin perl sürümü:
$ perl -ne '$s=$_ if $.%3==2;print $_ . $s and $s="" if $.%3==0 or $.%3==1;END{print $s if length $s}' input.txt