Come fare in modo che bash metta il prompt su una nuova riga dopo il comando cat?


17

Cosa ottengo:

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

Cosa voglio ottenere:

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

C'è un modo in cui posso catcomportarmi in questo modo?

Sto usando bash su Mac OS X.

Risposte:


15

La maggior parte degli strumenti unix sono progettati per funzionare bene con file di testo. Un file di testo è costituito da una sequenza di righe. Una linea è composta da una sequenza di caratteri stampabili che termina con un carattere di nuova riga. In particolare, l'ultimo carattere di un file di testo non vuoto è sempre un carattere di nuova riga. Evidentemente, example.txtcontiene solo some textsenza una nuova riga finale, quindi non è un file di testo.

catfa un lavoro semplice; trasformare file arbitrari in file di testo non fa parte di quel lavoro. Alcuni altri strumenti trasformano sempre il loro input in file di testo; se non sei sicuro che il file che stai visualizzando termina con una nuova riga, prova a eseguire awk 1invece di cat.

Puoi fare in modo che bash visualizzi il suo prompt sulla riga successiva se il comando precedente ha lasciato il cursore in un punto diverso dall'ultimo margine. Inserisci questo nella tua .bashrc(variante di GetFree di una proposta di Dennis Williamson ):

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

Grazie mille per una soluzione funzionante e una breve spiegazione! Capisco che questo è un po 'troppo per i poveri cat, quindi lo terrò come ultima risorsa per il momento in cui questo problema inizia a disturbarmi di nuovo.
Stanislav Shabalin,

Poiché questa è la preferenza bash, può rompere i comandi di piping?
Stanislav Shabalin,

1
@StanislavShabalin Questo non influisce sulle tubazioni, ma solo sul prompt.
Gilles 'SO- smetti di essere malvagio' il

Devo rimuovere "-1" dopo "COLONNE" affinché funzioni correttamente.
rafak,

Questa soluzione provoca lo spostamento del prompt quando viene ridimensionata la finestra del terminale. Ho scoperto che per farlo funzionare in modo affidabile ho dovuto inserire la colonna corrente PROMPT_COMMANDe, se non è 0, usare una newline ( \n) come primo carattere di PS1.
Brian Donovan,

10

Preferisco il seguente metodo ...

cat example.txt ; echo

Questo non valuta i contenuti di example.txto aggiunge occasionalmente una nuova riga. Fa eco a una nuova riga una volta che il gatto è finito, è facile da ricordare e nessuno sta pensando se stanno usando correttamente le citazioni forti o deboli.

L'unico aspetto negativo, in realtà, è che otterrai una nuova riga aggiuntiva se il file ha una nuova riga finale.


7

Ho iniziato a utilizzare la risposta di @ Gilles, ma ho scoperto che se il terminale avesse cambiato il numero di colonne il prompt non sarebbe più stato all'inizio di una riga come previsto. Ciò può accadere per una serie di motivi, tra cui tmux / suddivisioni dello schermo, ridimensionamento manuale di un contenitore GUI, modifiche dei caratteri, ecc.

Quello che volevo davvero era qualcosa che avrebbe aggiunto una nuova riga se il terminale avesse iniziato a stampare il suo prompt in qualcosa di diverso dalla prima colonna. Per fare questo ho dovuto capire come ottenere la colonna corrente, che ho usato questa risposta per ottenere. La configurazione del prompt di lavoro finale è di seguito:

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

Uso questa soluzione, ma quando provo a incollare comandi multi-linea nella mia shell, sembra finire per mangiare parte / tutte le linee dopo la prima incollata. c'è qualche soluzione a questo?
solo l'

@onlynone forse i tuoi comandi non vengono cancellati individualmente e in tempo per __get_terminal_column?
Androbin,

Invece di PS1="\n"ho solo echoe non ho bisogno di modificare PS1.
Androbin,

4

Il problema potrebbe essere che il tuo esempio.txt non ha una nuova riga alla fine del tuo file.


2
Il fatto è che non mi importa se il file ha una riga alla fine o no. Voglio essere in grado di vedere l'output del gatto più chiaro e non così dirompente :-) E capisco che non catè il lavoro, quindi probabilmente sto cercando una soluzione alternativa.
Stanislav Shabalin,

1
Questa è una non risposta che example.txtnon ha una nuova riga alla fine del file è il punto centrale della domanda.
Willem D'Haeseleer,

2

Se insisti nell'utilizzare cat, questo funziona per entrambi i tipi di file, con e senza una nuova riga alla fine:

echo "`cat example.txt`"

Puoi trasformarlo in una funzione con un nome a tua scelta (anche cat) nel tuo .bashrc:

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

1
Ora è un po 'troppo, anche se funziona ;-) Grazie comunque!
Stanislav Shabalin,

0

puoi anche aggiungere a .bashrc

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

per me va bene.


1
Ciò aggiungerebbe anche una riga vuota aggiuntiva nel terminale ogni volta che un'utilità genera qualcosa che è correttamente terminato da una nuova riga.
Kusalananda

Questo è vero. Ma è semplice e se non ti dà fastidio avere una linea in più ...
klaus
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.