Her satırı birkaç kez tekrarlayın


17

Bir dosyadaki her satırın belirli sayıda tekrarlanmasını istiyoruz.

örneğin, her satırı dört kez tekrarlayın:

a
b
c

dönüşür:

a
a
a
a
b
b
b
b
c
c
c
c

Biraz arama yaptım ve tersini yapan çizgiler boyunca birçok soru ve cevap var, örneğin yinelenen satırları tek satırlara birleştirmek ve belki de satırları tekrar yazdırarak iki katına çıkarmak.

Bunu C'de yapmak kolay olurdu, ancak keşke yerel komutlar hakkında daha fazla bilgi sahibi olsaydım, bu yüzden bu tür bir kerelik atışlara her zaman başvurmak zorunda kalmam.

Yanıtlar:


19
  • Perl:

    perl -ne 'for$i(0..3){print}' file

    ve ben sadece serin çünkü @ derobert tarafından yorum olarak yayınlanan bir eklemek zorunda:

    perl -ne 'print "$_" x4'
  • awk ve varyantları:

    awk '{for(i=0;i<4;i++)print}' file
  • bash

    while read line; do for i in {1..4}; do echo "$line"; done; done < file

1
awk's fortekrarlamak için sadece bir komut varsa parantez ihtiyacı yok. Ve loop: perlkullanıyorsanız daha basittir . foreachfor$i(0..3){print}
manatwork

4
Alternatif perl: perl -ne 'print(($_)x4)'. Ayrıca, $linebash sürümünüzde (echo olarak) alıntı yapmalısınız .
derobert

Benim durumumda Windows satır sonlarına ihtiyacım vardı. Burada görüldüğü gibi ile elde edebilirsinizBEGIN { ORS="\r\n" }
The Red Pea

34

Bunun bir golf maçına dönüşüp dönüşmediğini merak ediyorum :

sed 'p;p;p' 
awk '1;1;1;1' 
perl -lpE 'say;say;say'   # if Paul McCartney and Michael Jackson were hackers...

Açıklama:

sed'in pkomutu geçerli satırı yazdırmaktır. Varsayılan davranış, bir sonraki satıra geçmeden hemen önce geçerli satırı yazdırmaktır (bu yüzden sed'in -nonu kapatmanıza izin vermesi gerekir). Bazı yaşlı sümüklerde noktalı virgül yoktur (bence) bu yüzden yapmanız gerekebilirsed -e p -e p -e p

Awk condition {action}çiftlerle çalışır . Eylem atlanırsa, varsayılan koşul doğruysa geçerli satırı yazdırmaktır. Awk, birçok C benzeri dil gibi, 1gerçek gibi davranır . (Tamlık için, koşul belirtilmezse, eylem her kayıt için yürütülür.)

Birçok perl işlevi "varsayılan" değişkeninden yararlanır. Bu tek astar eşdeğerdir (perl 5.16'da):

$ perl -MO=Deparse -lpE 'say;say;say'
BEGIN { $/ = "\n"; $\ = "\n"; }
use feature 'current_sub', 'evalbytes', 'fc', 'say', 'state', 'switch', 'unicode_strings', 'unicode_eval';
LINE: while (defined($_ = <ARGV>)) {
    chomp $_;
    say $_;
    say $_;
    say $_;
}
continue {
    die "-p destination: $!\n" unless print $_;
}

1
+1, eğer öyleyse, kazanıyorsunuz :) 1awk'ta tam olarak ne yapar ? Kestirme için print $0?
terdon

3
Awk ifadeleri bir koşul ve bir bloktan oluşur, ya isteğe bağlıdır, ancak bir tane olmalıdır. Varsayılan koşul 1(true) şeklindedir; varsayılan blok ile eşdeğerdir {print}. Yani ifade 1, geçerli satır arabelleğini ( {print}) yazdırmak anlamına gelir . ( {print}ve {print $0}çoğunlukla aynı, qed.)
Arcege

sedKomut sonlandırıcı olarak noktalı virgül desteklemeyen bir ses duymadım ; gerçekten böyle bir şey var mı?
Wildcard


4

Sen gerektirmeden yapabilirsiniz sed, perlveya awk.

$ for i in `cat <file>` ; do seq <#> <#> | xargs -i -- echo $i ; done

veya while döngüsü kullanarak:

$ while read i ; do seq <#> <#> | xargs -i -- echo $i ; done < <file>

Örnekler

döngü için
$ for i in `cat sample.txt` ; do seq 1 3 | xargs -i -- echo $i ; done
a
a
a
b
b
b
c
c
c
döngü sırasında
$ while read i; do seq 1 2| xargs -i -- echo $i;done < sample.txt
a
a
b
b
c
c

For döngüsü sürümü boşluk içeren herhangi bir satırda kırılacağını düşünüyorum, bu yüzden while döngüsü tercih edilmelidir. Aksi takdirde, kabuk çözümleri için enayi olduğum için +1.
evilsoup

@evilsoup - evet başka birisi de başka bir soru-cevap üzerine yayınlanan bazı kod üzerinde bu bahsetti. Ben süre için birincil avantajı ise, while döngüsü $ IFS ayırıcı hoşgörülü olduğunu düşünüyorum ve satır sonu bölünecek iken, $ IFS üzerinde böler.
slm

1

Tamamen kabuk kullanarak:

repeats=4
while read line; do yes $line|head --lines=$repeats; done < infile > outfile

Biri evet yapmak için nasıl --helpbir seçenek yerine bir dize olarak düşünmek biliyor mu ? [nerede veya başka bir seçenek lineolduğunu düşünün --help]
user176581

evet,yes -- --help
don_crissti

Kullanmak yesve headbu "tamamen kabuk değil" anlamına gelir
glenn jackman

1

Bu sizin için işe yarayabilir (GNU sed):

sed 'h;:a;s/[^\n]\+/&/4;t;G;ba' file

Her satırı 4 kez tekrarlar.

İsterseniz:

sed 'h;:a;s/\n/&/3;t;G;ba' file

Her satırı 3 kez daha tekrarladığınız yer.


1

cevabını @potong yerine boş çizgilerle çalışma değil \+ile *düzeltmek gerekir:

sed 'h;:a;s/[^\n]*/&/4;t;G;ba' file
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.