Appending a line to a file in the cat command?
Solution 1
You can leverage cat
's ability to read from stdin combined with it's ability to read multiple files to achieve this.
~$ cat file.txt
Hello from file.txt
~$ echo "My final line" | cat file.txt -
Hello from file.txt
My final line
You can also prepend a line, as such:
~$ echo "My final line" | cat - file.txt
My final line
Hello from file.txt
Note that you are not limited to a single line. cat
will read from stdin until it reaches EOF. You can pass the output from curl
, for example, to prepend or append to the output of cat
.
~$ curl -s http://perdu.com | cat file.txt -
Hello from file.txt
<html><head><title>Vous Etes Perdu ?</title></head><body><h1>Perdu sur l'Internet ?</h1><h2>Pas de panique, on va vous aider</h2><strong><pre> * <----- vous êtes ici</pre></strong></body></html>
Solution 2
For appending a line to a file, you can just use shell append redirection operator, >>
(the file will be open(2)
-ed with O_APPEND
flag):
echo 'My final line' >>file.txt
Now, if you want just to view the content of the file with a final line appended, i would use cat
with two arguments:
- First, your file obviously, let's say
file.txt
- Second argument would be the string of your choice, and to pass the string as a filename (as
cat
only deals with files) you can leverage process substitution,<()
, which would return a file descriptor (/proc/self/fd/<fd_number>)
.
Putting these together:
cat file.txt <(echo 'My final line')
If you want the output to be paged, assuming less
is your favorite pager:
less file.txt <(echo 'My final line')
Solution 3
sed -e '$aMy final line' file.txt
From man sed
the option -e
-e script, --expression=script
add the script to the commands to be executed
$
matches the last line and a
appends the string.
If you wanted to permanently append the line to the file, use -i
-i[SUFFIX], --in-place[=SUFFIX]
edit files in place (makes backup if SUFFIX supplied)
Changing the command to
sed -i -e '$aMy final line' file.txt
Solution 4
It was already clarified in the comments to the question, but adding it again as an answer here.
The command noted in the question,
(cat file.txt ; echo "My final line") | other command
works as is expected – all the output from the subshell formed by the parentheses is piped to the second command.
If the file doesn't end with a new line, the echoed string is appended to the last line – this is common with all the other solutions here, and can be solved by adding another (empty) echo before.
Related videos on Youtube
DoubleBass
Updated on September 18, 2022Comments
-
DoubleBass over 1 year
I can do
cat file.txt
to get the contents of a file but I also want to tack on a final line of my own choosing.I tried piping
(cat file.txt ; echo "My final line") |
but only the final line is getting passed through the pipe. How can I join the cat and final line?Edit for a point of clarification: I do not wish to modify the file itself. I am aware that if this were the case I could do
echo "My final line" >> file.txt
orecho "My final line" | tee -a file.txt
but I am only trying to do the append within the context of this particular command so I can pipe in the concatenation offile.txt
and"My final line"
.-
edwinksl over 6 yearsMaybe something like
echo "My final line" >> file.txt
? -
DoubleBass over 6 yearsI don't want to actually append the line to the file object, just in the command / piping. I already know that I can append the line with
>>
if I wanted to edit the file itself. -
Bracken over 6 yearsHave you accidentally erased
file.txt
? Your pipe snippet should work. -
Bryan Boettcher over 6 years@DoubleBass: Mathieu Mitchell's answer is a better one, as it doesn't modify the file (either in-memory or on disk), but instead utilizes a feature of a built-in command.
-
-
jpaugh over 6 years
<()
works for bash, but what other shells does it work for? Ksh? Dash? -
heemayl over 6 years@jpaugh
ksh
,zsh
-- Yes,dash
-- No. -
ctrl-alt-delor over 6 years
(cat file.txt ; echo "My final line") | …
would also do it. But usingcat
for what it was designed for is better +1. -
ctrl-alt-delor over 6 yearsThis modifies the original.
-
muru over 6 yearsIf the file doesn't end with a newline, I'd use
awk
:awk 1 file.txt; echo "My final line"
.awk 1 file
is a nice trick to compensate for missing EOL at the end of the file. -
Wildcard over 6 yearsUse single quotes and you don't need the backslash.
-
David Foerster over 6 years@ctrl-alt-delor: Sub-shells also have the disadvantage of an additional process to fork which is relatively expensive. Try for example
echo "$$" "$BASHPID" | head -q -n 1 /proc/mounts - | cat
vs.( head -q -n 1 /proc/mounts; echo "$$" "$BASHPID" ) | cat
or even{ head -q -n 1 /proc/mounts; echo "$$" "$BASHPID"; } | cat
. -
fregante almost 5 yearsIf the file doesn't end with a new line, you can also just use
echo "\nMy final line"
without having to depend onawk