Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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.

share|improve this question

6 Answers 6

up vote 8 down vote accepted
  • 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
    
share|improve this answer
    
Don't need seq for the bash answer: for i in {1..4} –  glenn jackman Jul 5 '13 at 16:12
    
@glennjackman thanks, I always forget that. –  terdon Jul 5 '13 at 16:14
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
    
@manatwork thanks, I was not aware of the for$var() format and thought that using for would mean that $_ is assigned to the values in 0..3 as in print for(0..3), TMTOWTDI!. Answer updated. –  terdon Jul 5 '13 at 16:42
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

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 $_;
}
share|improve this answer
    
+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
1  
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
sed -n '{p;p;p;p;}' file

awk '{print;print;print;print;}' file
share|improve this answer

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
share|improve this answer
    
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

Using purely shell:

repeats=4
while read line; do yes $line|head --lines=$repeats; done < infile > outfile
share|improve this answer
    
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

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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