JWAspin
JWAspin

Reputation: 352

Bash: redirect `cat` to file without newline

I have two files that I am concatenating into a single file, but I am also adding user input between the two files. The problem is that a newline is being inserted after the first file, the rest of it works as desired.

touch newFile
cat file1 > newFile
echo -n $userInput >> newFile
cat file2 >> newFile

How do I prevent or remove the newline when file1 is added to newFile? If I cat file1 there seems to be a newline added by cat but everything I see about cat says it doesn't do that. If I vim file1 there's not a blank line at the end of the file that would indicate the newline is a part of the file, so either cat is actually adding a newline, or the redirect > is doing it, or echo adds a newline at the beginning of its output, none of which would be desirable in this situation. One solution I saw was to use

cat file1 | tr -d '\n'

but that discards all the newlines in the file, also not desirable. So, to repeat my question:

How do I cat file1 into the new file and add user input without adding the newline between them?

(cat is not a requirement, but I am not familiar with printf, so if that's the solution then please elaborate on its use).

Upvotes: 8

Views: 25244

Answers (3)

dawg
dawg

Reputation: 103884

With these inputs:

userInput="Test Test Test"

echo "Line 1
Line 2
Line 3" >file1

echo "Line 4
Line 5
Line 6" >file2

I would do:

printf "%s%s%s" "$(cat file1)" "$userInput" "$(cat file2)" >newfile

The creation of >newfile is equivalent to touch and adding content in your first step. A bit easier to see intent with this.

I get:

$ cat newfile
Line 1
Line 2
Line 3Test Test TestLine 4
Line 5
Line 6

Upvotes: 6

that other guy
that other guy

Reputation: 123490

Like all other Unix tools, Vim considers \n a line terminator and not a line separator.

This means that a linefeed after the last piece of text will be considered part of the last line, and will not show an additional blank line.

If there is no trailing linefeed, Vim will instead show [noeol] in the status bar when the file is loaded:

foo
~
~
~
~
~
"file" [noeol] 1L, 3C            1,1           All
        ^---- Here

So no, the linefeed is definitely part of your file and not being added by bash in any way.

If you want to strip all trailing linefeeds, you can do this as a side effect of command expansion:

printf '%s' "$(<file1)" >> newfile

Upvotes: 4

JWAspin
JWAspin

Reputation: 352

touch newFile
echo -n "$(cat file1)" > newFile
echo -n $userInput >> newFile
cat file2 >> newFile

That did the trick.

Upvotes: 0

Related Questions