如何让 bash 在 cat 命令后将提示符换行?

如何让 bash 在 cat 命令后将提示符换行?

我得到什么:

host:~ user$ cat example.txt
some texthost:~ stas$

我想得到什么:

host:~ user$ cat example.txt
some text
host:~ stas$

有什么办法可以让我cat表现得像这样吗?

我在 Mac OS X 上使用 bash。

答案1

我更喜欢以下方法...

cat example.txt ; echo

这不会评估内容example.txt或偶尔添加换行符。一旦猫完成,它只是回显换行符,很容易记住,并且没有人考虑他们是否正确使用了强引用或弱引用。

实际上,唯一的缺点是,如果文件有自己的尾随换行符,您将获得额外的换行符。

答案2

大多数 UNIX 工具都设计为可以很好地处理文本文件。文本文件由一系列行组成。一行由一系列以换行符结尾的可打印字符组成。特别是,非空文本文件的最后一个字符始终是换行符。显然,example.txt仅包含some text,没有最后的换行符,因此它不是一个文本文件。

cat做简单的工作;将任意文件转换为文本文件不是该工作的一部分。其他一些工具总是将其输入转换为文本文件;如果您不确定所显示的文件以换行符结尾,请尝试运行awk 1而不是cat.

如果上一个命令将光标留在最后一个边距以外的位置,则可以使 bash 在下一行显示提示符。把这个放在你的.bashrc(变体通过获取免费一项提案的作者:丹尼斯·威廉姆森):

shopt -s promptvars
PS1='$(printf "%$((COLUMNS-1))s\r")'$PS1

答案3

我开始使用 @Gilles 的答案,但发现如果终端更改了列数,提示将不再按预期位于行的开头。发生这种情况的原因有多种,包括 tmux/屏幕分割、手动调整 GUI 容器的大小、字体更改等。

我真正想要的是,如果终端开始在第一列以外的地方打印提示符,则会添加换行符。为此,我需要弄清楚如何获取我使用的当前列这个答案要得到。最终工作提示配置如下:

###
# 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"

答案4

如果您坚持使用cat,这适用于两种类型的文件,无论末尾有或没有换行符:

echo "`cat example.txt`"

您可以将其转换为具有您选择的名称(甚至cat)的函数.bashrc

cat1(){ echo "`/bin/cat $@`";}

相关内容