1

I was trying to merge all the text files in to one file. All the text files has one column and equal number of rows. My data file names are data_1.txt, data_2.txt, data_3.txt, . . . data_n.txt. where n is the number of text files to be merged. I want the merge from 1 to n in their order. I tried the following code, but it doesn't work as I wanted. It doesn't keep the column order.

My sample data looks like

data_1.txt

0.020085
0.0017361
0.77963
0.98659
0.33102
0.099835
0
0
0.073004
0.29978

data_2.txt

0.021407
0.0017191
0.82385
1.0449
0.34593
0.10535
0
0
0.078362
0.31509

data_3.txt

0.022706
0.0016876
0.85447
1.0922
0.35556
0.11063
0
0
0.083983
0.32536

required output

combined.txt

0.020085    0.021407    0.022706
0.0017361   0.0017191   0.0016876
0.77963 0.82385 0.85447
0.98659 1.0449  1.0922
0.33102 0.34593 0.35556
0.099835    0.10535 0.11063
0   0   0
0   0   0
0.073004    0.078362    0.083983
0.29978 0.31509 0.32536

Would you please help me in correcting my problem.

#!/bin/bash
paste data_*.txt > combined.txt
  • I'm not sure why you are using paste. You'd want cat *{1..n}.txt >> combined.txt – Valentin Bajrami Aug 11 '14 at 8:36
  • What do you mean by "their order"? Maybe editing your question and adding an example would help. – garethTheRed Aug 11 '14 at 8:39
  • Please give some example input and desired output. – cuonglm Aug 11 '14 at 8:41
  • @Gnouc, I added my sample data in my question. Thanks – AiB Aug 11 '14 at 8:50
  • @Abraham: How paste does not satify your requirement? – cuonglm Aug 11 '14 at 8:58
3

With zsh, you can affect the ordering of filename generations with glob qualifiers:

paste file_*.txt(n)

would turn on numeric sorting, that is put file_10.txt after file_9.txt

Note that if your files end in CR characters (as when they come from the Microsoft world), when output to a terminal, that character moves the cursor to the first column.

So for a file containing A\rB\rC\rn (as would happen if you pasted 3 MS-DOS formatted diles), cat that-file would seem to display only C. You can get rid of those CR characters by piping the above to tr -d '\r'

2

You can use brace expansion with paste to force an ordering:

$ paste data_{1..3}.txt
0.020085    0.021407    0.022706
0.0017361   0.0017191   0.0016876

Braces expand to several words, each of which has the parts to the left and right of the braces. The n..m syntax is a sequence expression:

A sequence expression takes the form {x..y[..incr]}, where x and y are either integers or single characters, and incr, an optional increment, is an integer. When integers are supplied, the expression expands to each number between x and y, inclusive.

The above command line will be expanded to:

paste data_1.txt data_2.txt data_3.txt

which includes the files in the right order. You can change the 3 to whatever the number of files is to get all the appropriate filenames.

The paste command joins its file arguments together columnwise in the order they're given as arguments, so the ordering of arguments matters. When you use * the filenames are expanded in alphabetical order, which will be wrong when you have 10 or more files, and so the columns will end up out of order then. For 1-9 files you'd be fine either way.

  • @Micheal Homer, Thank you very much. It does exactly what I wanted with a brief explanation. – AiB Aug 11 '14 at 10:04
-1
paste -d " " 1.txt 2.txt > 4.txt

There is another way using awk:

$ awk '{printf "%s",$1; getline < "1.txt" ; printf " %s\n",$1}' 2.txt

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.