How to append one file to another in Linux from the shell?
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 8
@BijayRungta: It sounds like you answered your own question. You’d pre-pend sudo to the cat command (and enter credentials if prompted).
you need to . chmod 777 /etc/default/docker to give yourself write permissions on that file — be sure to restore the old file permissions once done
@Sigur: Unless there’s a way to direct the output to two files at once, it would involve two invocations of the command.
@Sigur or have a look at the tee program: cat 1 | tee -a 2 3 . You can put as many files as you like after the —append (or -a for short) switch.
The >> operator appends the output to the named file or creates the named file if it does not exist.
This concatenates two or more files to one. You can have as many source files as you need. For example,
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:
. 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.
Append some text to the end of multiple files in Linux
How can I append the following code to the end of numerous php files in a directory and its sub directory:
bash : *.php: ambiguous redirect
6 Answers 6
I usually use tee because I think it looks a little cleaner and it generally fits on one line.
This is a Dantastic answer. 🙂 And since the OP is using bash, setting globstar will also allow it to handle PHP files in subdirectories.
what if i need to append a string to multiple specific files. I have multiple wordpress installs, and I need to add a string to the end of every file called functions.php. would this be possible with tee?
You don’t specify the shell, you could try the foreach command. Under tcsh (and I’m sure a very similar version is available for bash) you can say something like interactively:
foreach i (*.php) foreach> echo "my text" >> $i foreach> end
$i will take on the name of each file each time through the loop.
As always, when doing operations on a large number of files, it’s probably a good idea to test them in a small directory with sample files to make sure it works as expected.
Oops .. bash in error message (I’ll tag your question with it). The equivalent loop would be
for i in *.php do echo "my text" >> $i done
If you want to cover multiple directories below the one where you are you can specify
What about the files in the sub directories? I need to append on it as well. PS: I used the command for i in $a do echo «the code» >> $i done But in all files it appended twice and nothing happened to the files in the sub directories.
BashFAQ/056 does a decent job of explaining why what you tried doesn’t work. Have a look.
Since you’re using bash (according to your error), the for command is your friend.
for filename in *.php; do echo "text" >> "$filename" done
If you’d like to pull «text» from a file, you could instead do this:
for filename in *.php; do cat /path/to/sourcefile >> "$filename" done
Now . you might have files in subdirectories. If so, you could use the find command to find and process them:
find . -name "*.php" -type f -exec sh -c "cat /path/to/sourcefile >> <>" \;
The find command identifies what files using conditions like -name and -type , then the -exec command runs basically the same thing I showed you in the previous «for» loop. The final \; indicates to find that this is the end of arguments to the -exec option.
You can man find for lots more details about this.
The find command is portable and is generally recommended for this kind of activity especially if you want your solution to be portable to other systems. But since you’re currently using bash , you may also be able to handle subdirectories using bash’s globstar option:
shopt -s globstar for filename in **/*.php; do cat /path/to/sourcefile >> "$filename" done
You can man bash and search for «globstar» for more details about this. This option requires bash version 4 or higher.
NOTE: You may have other problems with what you’re doing. PHP scripts don’t need to end with a ?> , so you might be adding HTML that the script will try to interpret as PHP code.
Command to append line to a text file without opening an editor
You can append a line of text to a file by using the >> operator:
echo "hello world" >> my_file.txt
echo "alias list='ls -cl --group-directories-first'" >> config.fish
I use echo myself, but be careful, if you only specify one > then the file will truncate, not append. for a safer command you can use sed: sed -i ‘$a hello world’ filename
explanation: -i will update the file (otherwise it will just print the result to stdout), $ is regex that will match the end of the file, and a appends the following text to filename.
echo «hello world» >> my_file.txt does not create a new last line with HW , but add it to the string of the last line.
Maybe «Hello World» @7wp 🙂 It’s echo that adds the line break (making it a line as opposed to just a bunch of characters). You can switch off the line break at the end with -n .
Adding to Stefano’s answer, you can also use cat :
$ cat >> config.fish alias list='ls -cl --group-directories-first' > EOF
I often use this method but recently got caught when I pasted in a text that included some (escape) codes. It didn’t complain but when I checked the file there were chunks of pasted text missing. So use it with care!
@elmclose Sorry, which method? They work differently with respect to metacharacters. I think the second one doesn’t do anything with them, though there might be a few exceptions.
I meant EOF method. Very convenient and useful when you type or paste in readable text. But codes in my text confused the process. The file was a bash script that kept failing. Took me a while before I discovered what had happened.
There’s plenty of methods of appending to file without opening text editors, particularly via multiple available text processing utilities in Ubuntu. In general, anything that allows us to perform open() syscall with O_APPEND flag added, can be used to append to a file.
- GNU version of dd utility can append data to file with conv=notrunc oflag=append
printf "\nalias list='ls -cl --group-directories-first'\n" | dd conv=notrunc oflag=append bs=1 of=config.fish
sed -i '$a alias list='"'"'ls -cl --group-directories-first'"'" config.fish
#!/usr/bin/env python3 # read bytes from stdin, append to specified file import sys with open(sys.argv[1],'ab') as f: f.write(sys.stdin.buffer.read())
See also:
How to append output to the end of a text file
If file_to_append_to does not exist, it will be created.
$ echo "hello" > file $ echo "world" >> file $ cat file hello world
The problem is that echo removes the newlines from the string. How do you append to a file a string which contains newlines?
echo does not remove newlines from the string. If you fail to properly quote the argument, then the shell will split the string and pass arguments to echo and echo never even sees the newlines.
@Pmpr note that echo is not part of the solution, it is only part of the example I typed, and there are no escape sequences in the example.
echo "hello world" >> read.txt cat read.txt echo "hello siva" >> read.txt cat read.txt
then the output should be
hello world # from 1st echo command hello world # from 2nd echo command hello siva
echo "hello tom" > read.txt cat read.txt
You can use the >> operator. This will append data from a command to the end of a text file.
echo "Hi this is a test" >> textfile.txt
Do this a couple of times and then run:
You’ll see your text has been appended several times to the textfile.txt file.
Use command >> file_to_append_to to append to a file.
For example echo «Hello» >> testFile.txt
CAUTION: if you only use a single > you will overwrite the contents of the file. To ensure that doesn’t ever happen, you can add set -o noclobber to your .bashrc .
This ensures that if you accidentally type command > file_to_append_to to an existing file, it will alert you that the file exists already. Sample error message: file exists: testFile.txt
Thus, when you use > it will only allow you to create a new file, not overwrite an existing file.
Using tee with option -a (—append) allows you to append to multiple files at once and also to use sudo (very useful when appending to protected files). Besides that, it is interesting if you need to use other shells besides bash, as not all shells support the > and >> operators
echo "hello world" | sudo tee -a output.txt
This thread has good answers about tee
Use the >> operator to append text to a file.
I often confuse the two. Better to remember through their output:
> for Overwrite
$ touch someFile.txt $ echo ">" > someFile.txt $ cat someFile.txt > $ echo ">" > someFile.txt $ cat someFile.txt >
>> for Append
$ echo ">" > someFile.txt $ cat someFile.txt > $ echo ">" >> someFile.txt $ cat someFile.txt >>
this will append 720 lines (30*24) into o.txt and after will rename the file based on the current date.
Run the above with the cron every hour, or
while : do cmd >> o.txt && [[ $(wc -l
I would use printf instead of echo because it's more reliable and processes formatting such as new line \n properly.
This example produces an output similar to echo in previous examples:
printf "hello world" >> read.txt cat read.txt hello world
However if you were to replace printf with echo in this example, echo would treat \n as a string, thus ignoring the intent
printf "hello\nworld" >> read.txt cat read.txt hello world
I'd suggest you do two things:
- Use >> in your shell script to append contents to particular file. The filename can be fixed or using some pattern.
- Setup a hourly cronjob to trigger the shell script
For example your file contains :
1. mangesh@001:~$ cat output.txt 1 2 EOF
if u want to append at end of file then ---->remember spaces between 'text' >> 'filename'
2. mangesh@001:~$ echo somthing to append >> output.txt|cat output.txt 1 2 EOF somthing to append
And to overwrite contents of file :
3. mangesh@001:~$ echo 'somthing new to write' > output.tx|cat output.tx somthing new to write
This is misleading in many details. Spaces are not important and piping an empty output to cat is . just completely wacky. (It's empty because you just redirected standard output to a file.)
In Linux, You can use cat command to append file content to another file
In the previous command you will append content of fileName_1.txt to fileName_2.txt .
In Windows OS you can use type command
type fileName_1.txt >> fileName_2.txt
While all of these answers are technically correct that appending to a file with >> is generally the way to go, note that if you use this in a loop when for example parsing/processing a file and append each line to the resulting file, this might be much slower then you would expect.
A faster alternative might be this:
stringBuilder="" while read -r line; do # $'\n' prints a newline so we don't have to know what special chars the string contains stringBuilder+="$line"$'\n' done < "myFile.txt" echo "$stringBuilder" >$file
WARNING: you are reading all lines into memory; memory is a limited resource, so don't go doing this for gigantic files.