Not able to cat a string from a file under a string of another file

catnewlines

I have encountered a strange issue in concatenating the files using the cat command. I have two files with one string in each of them:

file1:

ABC

file2:

DEF

Either I do cat file1 file2 or I do cat file1 >> file2. I expect an output as shown below:

ABC  
DEF

However, I have a funny output like this:

ABCDEF

I have checked the files and there is no extra space or characters. However, when I do manual deleting from the back of the string, I don't even see a single character. It works fine. I suppose there must be some kind of "hidden" character or line which I can't see.

It has been bugging me a lot because I have tons of files to concatenate. I can't do the same thing manually.

Any help is appreciated.

Best Answer

paste is probably the easiest (which is not to mention extremely efficient) means at your disposal to handle this problem.

printf abc >file1
printf def >file2
paste -sd\\n file[12]

abc
def

When paste is invoked -serially it will read each of its named input files in-turn and paste the output of each line within each file on either a <tab> or a specified -delimiter string. While paste will always end its output of each named infile with a \newline, here the -delimiter is also specified to be a \newline, and so it will just basically cat its input to output with the exception that each file will always end in a \newline.


As Peter points out below, an empty file can cause paste to emit an extra \newline though. If this is an issue, practically the same method might be applied with sed which will not do so:

: > file0
sed '' file[012]

abc
def

Now with this method, though, (with GNU sed at least) there may be a different problem. Any sed will always write out a \newline before pulling in another line, but if it is the very last line of the whole concatenated series of input files, then some seds (such as GNU) may not append a newline at the end. For example, with my input files, the def is not followed on by a newline.

And if that is a problem, well...

sed '' file[012] | paste -sd\\n

...the above pipeline should probably cover all your bases.

Related Question