catコマンドの後にbashに新しい行にプロンプ​​トを表示させる方法は?


17

私が得るもの:

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

私が取得したいもの:

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

catこのように動作させる方法はありますか?

Mac OS Xでbashを使用しています。

回答:


15

ほとんどのUNIXツールは、テキストファイルで適切に動作するように設計されています。テキストファイルは、一連の行で構成されます。行は、改行文字で終わる印刷可能な文字のシーケンスで構成されます。特に、空でないテキストファイルの最後の文字は常に改行文字です。明らかに、最後の改行なしでexample.txtのみ含まれsome textているため、テキストファイルではありません。

cat簡単な仕事をします。任意のファイルをテキストファイルに変換することは、その仕事の一部ではありません。他のいくつかのツールは、入力を常にテキストファイルに変換します。表示しているファイルが改行で終わるかどうかわからない場合は、のawk 1代わりに実行してくださいcat

前のコマンドが最後のマージン以外の場所にカーソルを置いた場合、bashのプロンプトを次の行に表示させることができます。これをあなたの.bashrcDenis Williamsonによる提案のGetFreeによるバリエーション)に入れてください:

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

実用的なソリューションと簡潔な説明をありがとうございます!これは貧しい人にとっては少なからず理解できるcatので、この問題が再び私を悩ませ始めたときの最後の手段としてこれを維持します。
スタニスラフシャバリン

これはbashの設定であるため、パイプコマンドを中断できますか?
スタニスラフシャバリン

1
@StanislavShabalinこれはパイピングには影響せず、プロンプトにのみ影響します。
ジル 'SO-悪であるのをやめる'

これを正しく機能させるには、「COLUMNS」の後の「-1」を削除する必要があります。
-rafak

この解決策により、ターミナルウィンドウのサイズが変更されたときにプロンプ​​トが移動します。この作業を確実に行うには、現在の列を取得するPROMPT_COMMAND必要があり、0でない場合は\n、の最初の文字として改行()を使用する必要があることがわかりましたPS1
ブライアンドノヴァン14

10

私は次の方法を好む...

cat example.txt ; echo

これはexample.txt、改行の内容を評価したり、場合によっては改行を追加したりしません。猫が終わったら改行をエコーするだけで、覚えやすく、強引か弱引を正しく使用しているかについては誰も考えていません。

唯一の欠点は、実際には、ファイルに独自の末尾の改行がある場合、余分な改行を取得することです。


7

@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 /programming//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"

私はこのソリューションを使用しますが、複数行のコマンドをシェルに貼り付けようとすると、最初の行を貼り付けた後、行の一部/すべてを食べてしまうようです。これに対する解決策はありますか?
onlynone

@onlynoneおそらく、コマンドは個別にフラッシュされず、時間内に__get_terminal_column
アンドロビン

代わりに、変更する必要PS1="\n"echoありますPS1
アンドロビン

4

問題は、ファイルの最後にexample.txtの改行がないことです。


2
問題は、ファイルの最後に改行があるかどうかは気にしません。私は猫の出力をもっと明確に見て、この破壊的なものではないことを望んでいます:-)そして、私はそれがcat仕事ではないことを理解しているので、おそらくいくつかの回避策を探しています。
スタニスラフシャバリン

1
これはexample.txt、ファイルの最後に改行がないという無回答です。これが質問の要点です。
ウィレムD'Haeseleer

2

を使用する場合catは、最後に改行がある場合とない場合の両方のタイプのファイルで機能します。

echo "`cat example.txt`"

あなたはあなたの選択の名前(でさえcat)を持つ関数にそれを変えることができます.bashrc

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

1
今では、それが機能していても少し多すぎます;-)ありがとう!
スタニスラフシャバリン

0

同様に.bashrcに追加できます

PROMPT_COMMAND="printf '\n';$PROMPT_COMMAND"

私のために働く。


1
また、ユーティリティが改行で適切に終了されたものを出力するたびに、端末に余分な空白行が追加されます。
クサラナンダ

それは本当です。しかし...シンプルであり、それはあなたを気にしない場合は、余分なラインを持っている
クラウス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.