I have two files: file1
and file2
. How do I append the contents of file2
to file1
so that contents of file1
persist the process?
8 Answers
cat file2 >> file1
The >>
operator appends the output to the named file or creates the named file if it does not exist.
cat file1 file2 > file3
This concatenates two or more files to one. You can have as many source files as you need. For example,
cat *.txt >> newfile.txt
Update 20130902
In the comments eumiro suggests "don't try cat file1 file2 > file1
." The reason this might not result in the expected outcome is that the file receiving the redirect is prepared before the command to the left of the >
is executed. In this case, first file1
is truncated to zero length and opened for output, then the cat
command attempts to concatenate the now zero-length file plus the contents of file2
into file1
. The result is that the original contents of file1
are lost and in its place is a copy of file2
which probably isn't what was expected.
Update 20160919
In the comments tpartee suggests linking to backing information/sources. For an authoritative reference, I direct the kind reader to the sh man page at linuxcommand.org which states:
Before a command is executed, its input and output may be redirected using a special notation interpreted by the shell.
While that does tell the reader what they need to know it is easy to miss if you aren't looking for it and parsing the statement word by word. The most important word here being 'before'. The redirection is completed (or fails) before the command is executed.
In the example case of cat file1 file2 > file1
the shell performs the redirection first so that the I/O handles are in place in the environment in which the command will be executed before it is executed.
A friendlier version in which the redirection precedence is covered at length can be found at Ian Allen's web site in the form of Linux courseware. His I/O Redirection Notes page has much to say on the topic, including the observation that redirection works even without a command. Passing this to the shell:
$ >out
...creates an empty file named out. The shell first sets up the I/O redirection, then looks for a command, finds none, and completes the operation.
Just for reference, using ddrescue provides an interruptible way of achieving the task if, for example, you have large files and the need to pause and then carry on at some later point:
ddrescue -o $(wc --bytes file1 | awk '{ print $1 }') file2 file1 logfile
The logfile
is the important bit. You can interrupt the process with Ctrl-C
and resume it by specifying the exact same command again and ddrescue will read logfile
and resume from where it left off. The -o A
flag tells ddrescue to start from byte A in the output file (file1
). So wc --bytes file1 | awk '{ print $1 }'
just extracts the size of file1
in bytes (you can just paste in the output from ls
if you like).
As pointed out by ngks in the comments, the downside is that ddrescue will probably not be installed by default, so you will have to install it manually. The other complication is that there are two versions of ddrescue which might be in your repositories: see this askubuntu question for more info. The version you want is the GNU ddrescue, and on Debian-based systems is the package named gddrescue
:
sudo apt install gddrescue
For other distros check your package management system for the GNU version of ddrescue.
cat
can be the easy solution but that become very slow when we concat large files, find -print
is to rescue you, though you have to use cat once.
amey@xps ~/work/python/tmp $ ls -lhtr
total 969M
-rw-r--r-- 1 amey amey 485M May 24 23:54 bigFile2.txt
-rw-r--r-- 1 amey amey 485M May 24 23:55 bigFile1.txt
amey@xps ~/work/python/tmp $ time cat bigFile1.txt bigFile2.txt >> out.txt
real 0m3.084s
user 0m0.012s
sys 0m2.308s
amey@xps ~/work/python/tmp $ time find . -maxdepth 1 -type f -name 'bigFile*' -print0 | xargs -0 cat -- > outFile1
real 0m2.516s
user 0m0.028s
sys 0m2.204s