Repete cada linha várias vezes

13

Gostaria de ter cada linha em um arquivo repetida um número fixo de vezes.

por exemplo. tem cada linha repetida quatro vezes:

a
b
c

torna-se:

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

Eu fiz algumas pesquisas, e há muitas perguntas e respostas ao longo das linhas de fazer o inverso, por exemplo, mesclando linhas duplicadas em linhas únicas e talvez algumas sobre duplicação de linhas imprimindo-as novamente.

Seria fácil fazer isso em C, mas eu gostaria de saber mais sobre os comandos nativos para não ter que recorrer a esses tipos de jogadas fora de casa o tempo todo.

    
por Yimin Rong 05.07.2013 / 17:48

6 respostas

17
  • Perl:

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

    e eu tenho que adicionar este postado como um comentário por @derobert porque é legal:

    perl -ne 'print "$_" x4'
    
  • awk e variantes:

    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
    
por 05.07.2013 / 17:50
29

Gostaria de saber se isso está se transformando em uma correspondência golfe :

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

Explicação:

O comando p do sed é imprimir a linha atual. O comportamento padrão é imprimir a linha atual antes de ir para a próxima linha (é por isso que o sed tem -n para permitir que você a desative). Alguns seds mais antigos não têm o ponto-e-vírgula (eu acho), então é possível que você tenha que fazer sed -e p -e p -e p

O Awk funciona com condition {action} pares. Se a ação for omitida, o padrão será imprimir a linha atual se a condição retornar true. O awk, como muitas linguagens C, trata 1 como true. (Para completar, se a condição for omitida, a ação será executada para cada registro).

Muitas funções perl aproveitam a variável "default". Este one-liner é equivalente a (no perl 5.16):

$ 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 $_;
}
    
por 05.07.2013 / 18:12
4
sed -n '{p;p;p;p;}' file

awk '{print;print;print;print;}' file
    
por 05.07.2013 / 17:53
4

Você pode fazer isso sem exigir sed , perl ou awk .

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

ou usando um loop while:

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

Exemplos

para loop
$ for i in 'cat sample.txt' ; do seq 1 3 | xargs -i -- echo $i ; done
a
a
a
b
b
b
c
c
c
while loop
$ while read i; do seq 1 2| xargs -i -- echo $i;done < sample.txt
a
a
b
b
c
c
    
por 05.07.2013 / 19:19
1

Usando puramente shell:

repeats=4
while read line; do yes $line|head --lines=$repeats; done < infile > outfile
    
por 06.07.2013 / 17:32
1

Isso pode funcionar para você (GNU sed):

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

Repetirá cada linha 4 vezes.

Ou se preferir:

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

Onde você repete cada linha mais 3 vezes.

    
por 10.07.2013 / 08:03