Wie mache ich Bash Put Prompt in einer neuen Zeile nach dem Befehl cat?

17

Was ich bekomme:

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

Was ich bekommen möchte:

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

Gibt es eine Möglichkeit, mich so zu catverhalten?

Ich verwende Bash unter Mac OS X.

Stanislav Shabalin
quelle

Antworten:

15

Die meisten Unix-Tools eignen sich gut für Textdateien. Eine Textdatei besteht aus einer Folge von Zeilen. Eine Zeile besteht aus einer Folge druckbarer Zeichen, die mit einem Zeilenumbruch enden. Insbesondere ist das letzte Zeichen einer nicht leeren Textdatei immer ein Zeilenvorschub. Offensichtlich example.txtenthält es nur some textkeinen abschließenden Zeilenumbruch, es handelt sich also nicht um eine Textdatei.

catmacht einen einfachen Job; Beliebige Dateien in Textdateien zu verwandeln, gehört nicht zu diesem Job. Einige andere Tools wandeln ihre Eingabe immer in Textdateien um. Wenn Sie nicht sicher sind, ob die angezeigte Datei mit einem Zeilenumbruch endet, versuchen Sie, awk 1anstelle von auszuführen cat.

Sie können die Eingabeaufforderung der Bash in der nächsten Zeile anzeigen lassen, wenn der vorherige Befehl den Cursor an einer anderen Stelle als dem letzten Rand positioniert hat. Fügen Sie dies in Ihre .bashrc( GetFree- Variante eines Vorschlags von Dennis Williamson ) ein:

shopt -s promptvars
PS1='$(printf "%$((COLUMNS-1))s\r")'$PS1
Gilles 'SO - hör auf böse zu sein'
quelle
Vielen Dank für eine funktionierende Lösung und kurze Erklärung! Ich verstehe, dass dies ein bisschen zu viel für die Armen ist cat, deshalb behalte ich dies als letzten Ausweg für die Zeit, in der dieses Problem mich wieder zu quälen beginnt.
Stanislav
Kann es, da dies eine Bash-Präferenz ist, Piping-Befehle unterbrechen?
Stanislav Shabalin
1
@StanislavShabalin Dies hat keine Auswirkungen auf die Rohrleitungen, nur auf die Eingabeaufforderung.
Gilles 'SO- hör auf böse zu sein'
Ich muss das "-1" nach "COLUMNS" entfernen, damit dies korrekt funktioniert.
Rafak
Diese Lösung bewirkt, dass die Eingabeaufforderung verschoben wird, wenn die Größe des Terminalfensters geändert wird. Ich fand, dass ich, um diese Arbeit zuverlässig zu machen, die aktuelle Spalte PROMPT_COMMANDeinlesen und, wenn sie nicht 0 ist, ein newline ( \n) als erstes Zeichen von verwenden musste PS1.
Brian Donovan
10

Ich bevorzuge die folgende Methode ...

cat example.txt ; echo

Hierdurch wird der Inhalt von example.txtZeilenumbrüchen nicht bewertet oder gelegentlich hinzugefügt. Sobald die Katze fertig ist, wird nur ein Zeilenumbruch angezeigt. Es ist leicht zu merken, und niemand denkt darüber nach, ob er starke oder schwache Zitate richtig verwendet.

Der einzige Nachteil ist, dass Sie einen zusätzlichen Zeilenumbruch erhalten, wenn die Datei einen eigenen abschließenden Zeilenumbruch enthält.

Amos
quelle
7

Ich begann mit der Verwendung von @ Gilles 'Antwort, stellte jedoch fest, dass sich die Eingabeaufforderung nicht mehr wie erwartet am Zeilenanfang befand, wenn das Terminal die Anzahl der Spalten änderte. Dies kann aus verschiedenen Gründen geschehen, z. B. durch Aufteilen von Tmux / Bildschirm, manuelles Ändern der Größe eines GUI-Containers, Schriftartenänderungen usw.

Was ich wirklich wollte, war etwas, das eine neue Zeile hinzufügt, wenn das Terminal seine Eingabeaufforderung an einer anderen Stelle als in der ersten Spalte ausgibt. Um dies zu tun mir , um herauszufinden , wie erforderlich die aktuelle Spalte zu bekommen, die ich verwenden , diese Antwort zu bekommen. Die endgültige Konfiguration der Arbeitsaufforderung ist unten:

###
# 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"
Brian Donovan
quelle
Ich verwende diese Lösung, aber wenn ich versuche, mehrzeilige Befehle in meine Shell einzufügen, scheint es, als würde sie nach dem ersten Einfügen einen Teil / alle Zeilen auffressen. Gibt es eine Lösung dafür?
Nur keiner
@onlynone evtl. werden deine befehle nicht einzeln und pünktlich gelöscht für __get_terminal_column?
Androbin
Anstatt PS1="\n"ich muss echound muss nur nicht modifizieren PS1.
Androbin
4

Das Problem könnte sein, dass Ihre example.txt am Ende Ihrer Datei keine neue Zeile enthält.

Bonsi Scott
quelle
2
Die Sache ist mir egal, ob die Datei am Ende einen Zeilenumbruch hat oder nicht. Ich möchte in der Lage sein, die Ausgabe von Katzen klarer und nicht so störend zu sehen :-) Und ich verstehe, dass dies nicht catder Job ist, also suche ich wahrscheinlich nach einem Workaround.
Stanislav Shabalin
1
Dies ist eine solche Nicht-Antwort, die example.txtkeine neue Zeile am Ende der Datei enthält. Dies ist der springende Punkt der Frage.
Willem D'Haeseleer
2

Wenn Sie darauf bestehen cat, funktioniert dies für beide Dateitypen, mit und ohne Zeilenumbruch am Ende:

echo "`cat example.txt`"

Sie können es in eine Funktion mit einem Namen Ihrer Wahl (gerade cat) umwandeln in .bashrc:

cat1(){ echo "`/bin/cat $@`";}
Holzgott
quelle
1
Nun, das ist ein bisschen zu viel, auch wenn es funktioniert ;-) Trotzdem danke!
Stanislav Shabalin
0

Sie können auch .bashrc hinzufügen

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

funktioniert bei mir.

klaus
quelle
1
Dies würde auch eine zusätzliche Leerzeile in das Terminal einfügen, wenn ein Dienstprogramm etwas ausgibt, das ordnungsgemäß durch eine neue Zeile abgeschlossen wird.
Kusalananda
Das ist wahr. Ist aber einfach und wenn es dich nicht stört eine extra Leitung zu haben ...
klaus