Reputation: 361
I have a column and I want to repeat it multiple times.
eg for example I want the following column
1
2
3
4
5
to repeat n times and become
1
2
3
4
5
1
2
3
4
5
1
2
3
4
5
1
2
3
4
5
.
.
.
etc
is this possible?
Upvotes: 0
Views: 2924
Reputation: 2841
Here's a portable awk
-based solution to do it using only built in variables with no looping at all :
{m,n,g}awk 'NF += __-(OFS = $-_)^_' RS='^$' FS='^$' ORS= __=3
1 <<<<
2
3
4
1 <<<<
2
3
4
1 <<<<
2
3
4
To repeat each row N times consecutively before the next row, then do
{m,n,g}awk 'NF += __-(OFS = "\n" $-_)^_' FS='^$' __=3
1 <<<<
1 <<<<
1 <<<<
2
2
2
3
3
3
4
4
4
If you wanna duplicate each row horizontally by N times, it's the same concept, slightly different :
{m,n,g}awk 'NF = __ *(OFS = $-_)^_' FS='^$' __=7
10101010101010
11111111111111
12121212121212
13131313131313
14141414141414
15151515151515
16161616161616
17171717171717
18181818181818
19191919191919
You can even make cute numeric pyramids by having the repeat count be based on NR
:
{m,n,g}awk 'NF = NR * (OFS=$-_)^_' FS='^$'
10
1111
121212
13131313
1414141414
151515151515
16161616161616
1717171717171717
181818181818181818
19191919191919191919
2020202020202020202020
So if you ever need 2^25
aka 32^5
copies for ASCII
string of 2^25
itself, then here's a pretty quick (0.45s
) and easy way to get it done with no loops at all :
out9: 256MiB 0:00:00 [ 591MiB/s] [ 591MiB/s] [ <=> ]
( echo 33554432 | mawk2 'NF=(OFS=$-_)^_*$-_' FS='^$'; )
0.30s user 0.10s system 89% cpu 0.454 total
1 268435457
Even if you wanna repeat pretty sizable files, it's reasonably speedy fast : e.g. less than 13 secs
for 9 x
a 1.85 GB
file :
{m,g}awk 'NF += __-(OFS = $-_)^_' RS='^$' FS='^$' ORS= __=9
out9: 16.6GiB 0:00:12 [1.30GiB/s] [1.30GiB/s] [ <=> ]
in0: 1.85GiB 0:00:00 [3.42GiB/s] [3.42GiB/s] [========>] 100%
5.48s user 4.44s system 77% cpu 12.809 total
112448475 17851902237 17851902237
If that's too slow for your needs, perhaps this way is a bit faster :
{m,g}awk '
BEGIN { FS = RS = "^$" }{__=sprintf("%*s",__, OFS = ORS = _)
gsub(".", "\\&", __) } sub(".+",__)' __=9
in0: 1.85GiB 0:00:00 [3.48GiB/s] [3.48GiB/s] [========>] 100%
out9: 16.6GiB 0:00:07 [2.12GiB/s] [2.12GiB/s] [ <=> ]
( pvE 0.1 in0 < "${m3t}" | LC_ALL=C mawk2 -v __=9 ; )
0.72s user 4.34s system 64% cpu 7.855 total
112448475 17851902237 17851902237
Upvotes: 0
Reputation: 203684
awk -v n=7 '{s = s $1 ORS} END{for (i=1;i<=n;i++) printf "%s", s}' file
Set n
to whatever number you like.
Alternatively, with GNU awk:
awk -v n=7 -v RS='\0' -v ORS= 'END{for (i=1;i<=n;i++) print}' file
Upvotes: 2
Reputation: 85815
Replace 3 with any value of n
and $1
with the column you want to print:
$ for i in {1..3}; do awk '{print $1}' file; done
1
2
3
4
5
1
2
3
4
5
1
2
3
4
5
You could do it just with awk
but you would have to store the whole file in memory:
$ awk '{a[NR]=$1}END{for(i=1;i<=3;i++)for(j=1;j<=NR;j++)print a[j]}' file
This is one of those occasions were using the shell constructs actually makes sense.
Upvotes: 2