13

Would like to have each line in a file repeated a fixed number of times.

e.g. have each line repeated four times:

a
b
c

becomes:

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

I've done some searching, and there are a lot of questions and answers along the lines of doing the reverse, e.g. merging duplicate lines into single lines, and maybe a few about doubling lines by printing them again.

It would be easy to do this in C, but I wish I knew more about the native commands so I wouldn't have to resort to these kinds of one-off throw-aways all the time.

17
  • Perl:

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

    and I have to add this one posted as a comment by @derobert because it is just cool:

    perl -ne 'print "$_" x4'
    
  • awk and variants:

    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 for not needs braces if there is only one command to repeat. And perl is simpler if you use foreach loop: for$i(0..3){print}. – manatwork Jul 5 '13 at 16:38
  • 4
    Alternative perl: perl -ne 'print(($_)x4)'. Also, you should quote $line (in echo) in your bash version. – derobert Jul 5 '13 at 16:46
  • In my case I needed Windows line-endings. as seen here can achieve with BEGIN { ORS="\r\n" } – The Red Pea Oct 27 '15 at 17:16
30

I wonder if this is turning into a golf match:

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

Explanation:

sed's p command is to print the current line. The default behaviour is to print the current line just before moving to the next line (that's why sed has -n to allow you to turn it off). Some older seds don't have the semicolon (I think) so it's possible you might have to do sed -e p -e p -e p

Awk works with condition {action} pairs. If the action is omitted, the default is to print the current line if the condition returns true. Awk, like many C-like languages, treats 1 as true. (For completeness, if the condition is omitted, the action will be executed for each record.)

Many perl functions take advantage of the "default" variable. This one-liner is equivalent to (on 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 $_;
}
  • 1
    +1, if it is, you're winning :) What exactly does the 1 do in awk? Shorthand for print $0? – terdon Jul 5 '13 at 16:15
  • 3
    Awk statements are made up of a condition and a block, either are optional, but one must be present. The default condition is 1 (true); the default block is equivalent to {print}. So the statement 1 would mean to print the current line buffer ({print}). ({print} and {print $0} are mostly the same, qed.) – Arcege Jul 5 '13 at 17:49
  • I've never heard of a sed that doesn't support semicolons as command terminators; is there really such a thing? – Wildcard May 6 '16 at 16:41
4
sed -n '{p;p;p;p;}' file

awk '{print;print;print;print;}' file
4

You can do this without requiring sed, perl, or awk.

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

or using a while loop:

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

Examples

for 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
  • I think the for loop version will break on any lines containing whitespace, so the while loop should be preferred. Otherwise, +1 since I'm a sucker for shell solutions. – evilsoup Jul 6 '13 at 13:27
  • @evilsoup - yes someone else mentioned this as well on some code I posted on another Q&A. I think that's the primary advantage of while over for, the while loop is tolerant of the $IFS separator and will split on end-of-line whereas the for splits on $IFS. – slm Jul 6 '13 at 13:30
1

Using purely shell:

repeats=4
while read line; do yes $line|head --lines=$repeats; done < infile > outfile
  • Does somebody know how to make yes consider --help as a string instead of an option? [consider the case where line is --help or another option] – user176581 Jul 6 '13 at 15:41
  • yes, yes -- --help – don_crissti Sep 13 '15 at 0:01
1

This might work for you (GNU sed):

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

Will repeat each line 4 times.

Or if you prefer:

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

Where you repeat each line 3 more times.

0

@potong 's answer does not work with empty lines, replacing \+ with * should fix it:

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.