Як змусити bash ставити підказку в новому рядку після команди cat?


17

Що я отримую:

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

Що я хочу отримати:

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

Чи є спосіб я змусити catсебе так поводитися?

Я використовую bash на Mac OS X.

Відповіді:


15

Більшість інструментів unix розроблені для того, щоб добре працювати з текстовими файлами. Текстовий файл складається з послідовності рядків. Рядок складається з послідовності символів для друку, що закінчуються символом нового рядка. Зокрема, останній символ не порожнього текстового файлу - це завжди символ нового рядка. Очевидно, він example.txtмістить лише some textвідсутність остаточного нового рядка, тому це не текстовий файл.

catробить просту роботу; перетворення довільних файлів у текстові файли не є частиною цього завдання. Деякі інші інструменти завжди перетворюють свої дані в текстові файли; якщо ви не впевнені, що файл, який відображається, закінчується новим рядком, спробуйте запустити awk 1замість cat.

Ви можете змусити bash відображати його підказку в наступному рядку, якщо попередня команда залишила курсор де-небудь, крім останнього поля. Помістіть це у вашій .bashrc(варіація пропозиції GetFree від Dennis Williamson ):

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

Дякую велике за робоче рішення та коротке пояснення! Я розумію, що це небагато для бідних cat, тому я буду тримати це в крайньому випадку на той час, коли це питання знову почне турбувати мене.
Станіслав Шабалін

Оскільки це баш-перевага, чи може вона порушувати трубопровідні команди?
Станіслав Шабалін

1
@StanislavShabalin Це не впливає на трубопроводи, лише на підказку.
Жил "ТАК - перестань бути злим"

Мені потрібно прибрати "-1" після "КОЛОНІВ", щоб це працювало правильно.
rafak

Це рішення призводить до переміщення підказки, коли зміниться вікно терміналу. Я виявив, що для надійної роботи мені довелося вставити поточний стовпець PROMPT_COMMANDі, якщо це не 0, використовувати новий рядок ( \n) як перший символ PS1.
Брайан Донован

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що у кінці файлу не є новий рядок - вся суть питання.
Willem D'Haeseleer

2

Якщо ви наполягаєте на використанні cat, це працює для обох типів файлів, з новим рядком і в кінці нового рядка:

echo "`cat example.txt`"

Ви можете перетворити його на функцію з назвою (рівним cat) ім'ям у вашому .bashrc:

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

1
Зараз це трохи забагато, навіть якщо це працює ;-) Хоча спасибі!
Станіслав Шабалін

0

ви також можете додати в .bashrc

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

працює для мене.


1
Це також додасть додатковий порожній рядок у терміналі, коли утиліта виводить щось, що належним чином закінчується новим рядком.
Kusalananda

Це правда. Але це просто, і якщо це не заважає вам мати додатковий рядок ...
klaus
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.