Column wise concatenation X no. of time Column wise concatenation X no. of time unix unix

Column wise concatenation X no. of time


I'd break the problem into two parts. First, create a tab-separated file of the desired dimensions and content (R rows by C columns, each cell containing string F). Then, paste that generated file onto the existing file:

R=$(wc -l < in.txt)   # num rows to generate, in this case same num lines as inputC=100000              # num columns to generateF=0.0                 # fixed valuepaste in.txt <(yes $F | head -$(($R * $C)) | pr -t$C -s$'\t')

For the sample input given, with C=5 columns, I get:

a       0.0     0.0     0.0     0.0     0.0b       0.0     0.0     0.0     0.0     0.0c       0.0     0.0     0.0     0.0     0.0

Breaking that pipeline down, inside out:

  • yes $F generates a stream of fixed values
  • head -$(($R * $C)) cuts the yes stream off after we've generated all the cells we need
  • pr -t$C -s$'\t' rotates the stream into a tab-separated table having the number of columns we want
  • <() puts all the above into an (essentially) temporary file
  • paste in.txt <() adjoins the two files, row-wise


Sed solutions

You could generate the string you want with printf and substitute the end of each line using sed:

$ num=5$ sed 's/$/'"$(for ((i=0; i<num; ++i)); do printf '\t%s' '0.0'; done)"'/' in.txta       0.0     0.0     0.0     0.0     0.0b       0.0     0.0     0.0     0.0     0.0c       0.0     0.0     0.0     0.0     0.0

where the value assigned to num is the number of columns to be added to your file.

The substitution replaces each line end ($) with the output of this command:

for (( i=0; i < num; ++i )); do    printf '\t%s' '0.0'done

If you don't mind using seq, this could be simplified to

sed 's/$/'"$(printf '\t0.0%.0s' $(seq 1 $num))"'/' in.txt

i.e., the command in the substitution is the one-liner

printf '\t0.0%.0s' $(seq 1 $num)

See for example the question How can I repeat a character in bash? for many options how to repeat a string in Bash using various tools.

Awk solution

This takes num as the number of columns to be added and uses a tab as the field separator:

awk -v num=5 -v OFS="\t" '{for (i=1; i<=num; ++i) $(NF+1) = "0.0"}1' in.txt

The for loop assigns 0.0 to the field one past the last, num times; the 1 gets the line printed.


you can also use for loop as below;

paste in.txt $(for i in {1..3}; do echo '0s'; done)

or

paste in.txt <(for i in {1..X}; do echo $(yes 0.0 | head -3); done)

or

paste in.txt <(for i in {1..3}; do echo $(yes 1.1 | head -$(wc -l in.txt| awk '{print $1}')); done)

Eg:

user@host:/tmp$ paste in.txt <(for i in {1..3}; do echo $(yes 1.1 | head -3); done)a   1.1 1.1 1.1b   1.1 1.1 1.1c   1.1 1.1 1.1