Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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.

share|improve this question

5 Answers 5

up vote 7 down vote accepted

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
share|improve this answer
    
Thank you a lot for a working solution and succinct explanation! I understand this is a bit much for poor cat, so I'll keep this as a last resort for the time when this issue starts bothering me again. –  Stanislav Shabalin Jan 6 '13 at 22:46
    
Since this is bash preference, can it break piping commands? –  Stanislav Shabalin Jan 6 '13 at 22:51
1  
@StanislavShabalin This doesn't affect piping, only the prompt. –  Gilles Jan 6 '13 at 22:52
    
I need to remove the "-1" after "COLUMNS" for this to work correctly. –  rafak May 5 '13 at 6:23
    
This solution causes the prompt to move when the terminal window is resized. I found that to make this work reliably I had to get the current column in PROMPT_COMMAND and, if it is not 0, use a newline (\n) as the first character of PS1. –  Brian Donovan Aug 25 at 18:03

The problem with that could be that your example.txt does not have a newline at the end of your file.

share|improve this answer
1  
The thing is I don't care if the file has a newline at the end or not. I wanna be able to see cat output more clear and not this disruptive :-) And I understand it's not cat's job so probably I'm looking for some workaround. –  Stanislav Shabalin Jan 6 '13 at 22:38

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 $@`";}
share|improve this answer
1  
Now that's a bit too much, even if it works ;-) Thanks though! –  Stanislav Shabalin Jan 6 '13 at 22:48

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 http://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"
share|improve this answer

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.