What I get:
host:~ user$ cat example.txt
some texthost:~ stas$
What I want to get:
host:~ user$ cat example.txt
some text
host:~ stas$
Is there a way I can make cat
behave like this?
I'm using bash on Mac OS X.
What I get:
host:~ user$ cat example.txt
some texthost:~ stas$
What I want to get:
host:~ user$ cat example.txt
some text
host:~ stas$
Is there a way I can make cat
behave like this?
I'm using bash on Mac OS X.
I prefer the following method...
cat example.txt ; echo
This doesn't doesn't evaluate the contents of example.txt
or occasionally add a newline. It just echos a newline once the cat is done, is easy to remember, and no one is thinking about whether they're using strong or weak quoting correctly.
The only downside, really, is that you'll get an extra newline if the file has its own trailing newline.
Most unix tools are designed to work well with text files. A text file consists of a sequence of lines. A line consists of a sequence of printable characters ending with a newline character. In particular, the last character of a non-empty text file is always a newline character. Evidently, example.txt
contains only some text
with no final newline, so it is not a text file.
cat
does a simple job; turning arbitrary files into text files isn't part of that job. Some other tools always turn their input into text files; if you aren't sure the file you're displaying ends with a newline, try running awk 1
instead of cat
.
You can make the bash display its prompt on the next line if the previous command left the cursor somewhere other than the last margin. Put this in your .bashrc
(variation by GetFree of a proposal by Dennis Williamson):
shopt -s promptvars
PS1='$(printf "%$((COLUMNS-1))s\r")'$PS1
cat
, so I'll keep this as a last resort for the time when this issue starts bothering me again.
– Stanislav Shabalin
Jan 06 '13 at 22:46
PROMPT_COMMAND
and, if it is not 0, use a newline (\n
) as the first character of PS1
.
– Brian Donovan
Aug 25 '14 at 18:03
I started using @Gilles's answer, but found that if the terminal changed the number of columns the prompt would no longer be at the start of a line as expected. This can happen for a variety of reasons, including tmux/screen splits, manual resizing of a GUI container, font changes, etc.
What I really wanted was something that would add a newline if the terminal would start printing its prompt at something other than the first column. To do this I needed to figure out how to get the current column, which I used this answer to get. The final working prompt configuration is below:
###
# Configure PS1 by using the old value but ensuring it starts on a new line.
###
__configure_prompt() {
PS1=""
if [ "$(__get_terminal_column)" != 0 ]; then
PS1="\n"
fi
PS1+="$PS1_WITHOUT_PREPENDED_NEWLINE"
}
###
# Get the current terminal column value.
#
# From https://stackoverflow.com/a/2575525/549363.
###
__get_terminal_column() {
exec < /dev/tty
local oldstty=$(stty -g)
stty raw -echo min 0
echo -en "\033[6n" > /dev/tty
local pos
IFS=';' read -r -d R -a pos
stty $oldstty
echo "$((${pos[1]} - 1))"
}
# Save the current PS1 for later.
PS1_WITHOUT_PREPENDED_NEWLINE="$PS1"
# Use our prompt configuration function, preserving whatever existing
# PROMPT_COMMAND might be configured.
PROMPT_COMMAND="__configure_prompt;$PROMPT_COMMAND"
__get_terminal_column
?
– Robin Richtsfeld
Nov 10 '19 at 22:21
PS1="\n"
I just have echo
and don't need to modify PS1
.
– Robin Richtsfeld
Nov 10 '19 at 22:29
The problem with that could be that your example.txt does not have a newline at the end of your file.
cat
's job so probably I'm looking for some workaround.
– Stanislav Shabalin
Jan 06 '13 at 22:38
example.txt
not having a new line at the end of the file is the whole point of the question.
– Willem D'Haeseleer
Nov 02 '15 at 05:24
If you insist on using cat
, this works for both types of files, with and without a newline at the end:
echo "`cat example.txt`"
You can turn it into a function with a name of your choice (even cat
) in your .bashrc
:
cat1(){ echo "`/bin/cat $@`";}
you can add to .bashrc as well
PROMPT_COMMAND="printf '\n';$PROMPT_COMMAND"
works for me.
If you use a modern Bash + terminal, you can use this solution based on a few similar answers:
# Get the "raw" form of the row and column
IFS=';' read -d R -p "$(tput u7)" -r -s row column
if [[ "$column" -ne 1 ]]
then
# Remove cruft from row to get the integer value
row="${row#*[}"
# Decrement column to avoid adding an empty space before the EOT marker
((column--))
# Add an inverted ␄ symbol and newline before the rest of $PS1
PS1="$(tput cup "$row" "$column")$(tput rev)␄$(tput sgr0)\n${PS1}"
fi
Pros:
tput
rather than escape sequences for easy searching and (probably?) wider support.$PS1
ensures that it's not clobbered by $PS1
if that contains a carriage return character.Cons:
tput
rather than escape sequences, so it might not work on older terminals.
echo
also masks the exit-status ofcat
, so that the final exit-status is that ofecho
rather than ofcat
. To avoid that, you could docat example.txt && echo
, to only executeecho
ifcat
was successful. – Kusalananda Jan 08 '22 at 09:34