Bagaimana cara membuat bash put prompt di baris baru setelah perintah cat?

17

Apa yang saya dapatkan:

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

Apa yang ingin saya dapatkan:

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

Apakah ada cara saya bisa catbersikap seperti ini?

Saya menggunakan bash di Mac OS X.

Stanislav Shabalin
sumber

Jawaban:

15

Sebagian besar alat unix dirancang untuk bekerja dengan baik dengan file teks. File teks terdiri dari urutan garis. Baris terdiri dari urutan karakter yang dapat dicetak yang diakhiri dengan karakter baris baru. Secara khusus, karakter terakhir dari file teks yang tidak kosong selalu merupakan karakter baris baru. Jelas, example.txthanya berisi some texttanpa baris akhir, jadi itu bukan file teks.

catmelakukan pekerjaan sederhana; mengubah file sewenang-wenang menjadi file teks bukan bagian dari pekerjaan itu. Beberapa alat lain selalu mengubah inputnya menjadi file teks; jika Anda tidak yakin file Anda menampilkan berakhir dengan baris baru, coba jalankan awk 1bukan cat.

Anda dapat membuat bash menampilkan prompt pada baris berikutnya jika perintah sebelumnya meninggalkan kursor di tempat lain selain margin terakhir. Masukkan ini ke dalam .bashrc(variasi Anda oleh GetFree dari proposal oleh Dennis Williamson ):

shopt -s promptvars
PS1='$(printf "%$((COLUMNS-1))s\r")'$PS1
Gilles 'SANGAT berhenti menjadi jahat'
sumber
Terima kasih banyak atas solusi yang bekerja dan penjelasan singkat! Saya mengerti ini sedikit banyak untuk orang miskin cat, jadi saya akan menyimpan ini sebagai pilihan terakhir untuk saat masalah ini mulai mengganggu saya lagi.
Stanislav Shabalin
Karena ini adalah preferensi bash, dapatkah itu memecah perintah perpipaan?
Stanislav Shabalin
1
@StanislavShabalin Ini tidak memengaruhi perpipaan, hanya konfirmasi.
Gilles 'SO- stop being evil'
Saya harus menghapus "-1" setelah "COLUMNS" agar ini berfungsi dengan benar.
rafak
Solusi ini menyebabkan prompt untuk bergerak ketika jendela terminal diubah ukurannya. Saya menemukan bahwa untuk membuat pekerjaan ini andal saya harus memasukkan kolom saat ini PROMPT_COMMANDdan, jika bukan 0, gunakan baris baru ( \n) sebagai karakter pertama PS1.
Brian Donovan
10

Saya lebih suka metode berikut ...

cat example.txt ; echo

Ini tidak mengevaluasi konten example.txtatau sesekali menambahkan baris baru. Itu hanya menggemakan baris baru setelah kucing selesai, mudah diingat, dan tidak ada yang memikirkan apakah mereka menggunakan kutipan yang kuat atau lemah dengan benar.

Satu-satunya downside, benar-benar, adalah bahwa Anda akan mendapatkan baris baru tambahan jika file tersebut memiliki baris tambahan sendiri.

Amos
sumber
7

Saya mulai menggunakan jawaban @ Gilles, tetapi menemukan bahwa jika terminal mengubah jumlah kolom prompt tidak akan lagi pada awal baris seperti yang diharapkan. Hal ini dapat terjadi karena berbagai alasan, termasuk pemisahan tmux / layar, pengubahan ukuran wadah GUI secara manual, perubahan font, dll.

Yang benar-benar saya inginkan adalah sesuatu yang akan menambah baris baru jika terminal akan mulai mencetak prompt-nya di sesuatu selain kolom pertama. Untuk melakukan ini, saya perlu mencari cara mendapatkan kolom saat ini, yang saya gunakan untuk mendapatkan jawaban ini . Konfigurasi prompt kerja terakhir adalah di bawah ini:

###
# 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
sumber
Saya menggunakan solusi ini, tetapi ketika saya mencoba untuk menempelkan perintah multi-line ke dalam shell saya, sepertinya akan memakan sebagian / semua baris setelah yang pertama ditempel. Apakah ada solusi untuk ini?
onlynone
@ ononone mungkin perintah Anda tidak memerah secara individual dan tepat waktu __get_terminal_column?
Androbin
Alih-alih PS1="\n"saya hanya perlu echodan tidak perlu memodifikasi PS1.
Androbin
4

Masalah dengan itu bisa jadi example.txt Anda tidak memiliki baris baru di akhir file Anda.

Bonsi Scott
sumber
2
Masalahnya adalah saya tidak peduli apakah file tersebut memiliki baris baru di akhir atau tidak. Saya ingin dapat melihat output kucing lebih jelas dan tidak mengganggu ini :-) Dan saya mengerti itu bukan catpekerjaan jadi mungkin saya sedang mencari solusi.
Stanislav Shabalin
1
Ini adalah jawaban yang example.txttidak memiliki baris baru di akhir file adalah inti dari pertanyaan.
Willem D'Haeseleer
2

Jika Anda bersikeras menggunakan cat, ini berfungsi untuk kedua jenis file, dengan dan tanpa baris baru di akhir:

echo "`cat example.txt`"

Anda dapat mengubahnya menjadi fungsi dengan nama pilihan Anda (datar cat) di .bashrc:

cat1(){ echo "`/bin/cat $@`";}
woodengod
sumber
1
Nah, itu agak terlalu banyak, bahkan jika itu bekerja ;-) Terima kasih!
Stanislav Shabalin
0

Anda dapat menambahkan ke .bashrc juga

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

bekerja untukku.

klaus
sumber
1
Ini juga akan menambah baris kosong tambahan di terminal setiap kali utilitas mengeluarkan sesuatu yang diakhiri dengan benar oleh baris baru.
Kusalananda
Itu benar. Tetapi sederhana, dan jika tidak mengganggu Anda untuk memiliki garis tambahan ...
klaus