Reputation: 122022
I have a file with some strings delimited by newline, in.txt
:
$ echo -e 'a\nb\nc' > in.txt
$ cat in.txt
a
b
c
And I need to concat a certain fix values to the file for each line in in.txt
column-wise, so first I did:
$ yes '0.0' | head -n 3
0.0
0.0
0.0
Then paste
it:
$ yes '0.0' | head -n 3 > 0s
$ paste in.txt 0s
a 0.0
b 0.0
c 0.0
The question is how do I perform the column wise concatenation X no. of times? Imagine X is 100,000 , manually typing in paste in.txt 0s 0s 0s ...
is not feasible.
Upvotes: 3
Views: 143
Reputation: 39364
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 input
C=100000 # num columns to generate
F=0.0 # fixed value
paste 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.0
b 0.0 0.0 0.0 0.0 0.0
c 0.0 0.0 0.0 0.0 0.0
Breaking that pipeline down, inside out:
yes $F
generates a stream of fixed valueshead -$(($R * $C))
cuts the yes stream off after we've generated all the cells we needpr -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 filepaste in.txt <()
adjoins the two files, row-wiseUpvotes: 3
Reputation: 52112
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.txt
a 0.0 0.0 0.0 0.0 0.0
b 0.0 0.0 0.0 0.0 0.0
c 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.
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.
Upvotes: 2
Reputation: 68
What about something like this
paste in.txt \`printf '0s %.0s' {1..$X}\`
I got that printf part from https://superuser.com/questions/86340/linux-command-to-repeat-a-string-n-times
Upvotes: 1
Reputation: 4112
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.1
b 1.1 1.1 1.1
c 1.1 1.1 1.1
Upvotes: 1