Làm thế nào để tạo bash put prompt trên một dòng mới sau lệnh cat?


17

Những gì tôi nhận được:

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

Những gì tôi muốn nhận được:

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

Có cách nào để tôi có thể catcư xử như thế này không?

Tôi đang sử dụng bash trên Mac OS X.

Câu trả lời:


15

Hầu hết các công cụ unix được thiết kế để hoạt động tốt với các tệp văn bản. Một tập tin văn bản bao gồm một chuỗi các dòng. Một dòng bao gồm một chuỗi các ký tự có thể in kết thúc bằng một ký tự dòng mới. Cụ thể, ký tự cuối cùng của tệp văn bản không trống luôn là ký tự dòng mới. Rõ ràng, example.txtchỉ chứa some textkhông có dòng mới cuối cùng, vì vậy nó không phải là một tệp văn bản.

catlàm một công việc đơn giản; biến các tệp tùy ý thành tệp văn bản không phải là một phần của công việc đó. Một số công cụ khác luôn biến đầu vào của chúng thành tệp văn bản; nếu bạn không chắc chắn tệp bạn đang hiển thị kết thúc bằng một dòng mới, hãy thử chạy awk 1thay vì cat.

Bạn có thể làm cho bash hiển thị dấu nhắc của nó trên dòng tiếp theo nếu lệnh trước đó để con trỏ ở đâu đó ngoài lề cuối cùng. Đặt điều này trong .bashrc(biến thể của GetFree của một đề xuất của Dennis Williamson ):

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

Cảm ơn bạn rất nhiều cho một giải pháp làm việc và giải thích ngắn gọn! Tôi hiểu điều này hơi nhiều đối với người nghèo cat, vì vậy tôi sẽ giữ điều này như là phương sách cuối cùng cho đến khi vấn đề này bắt đầu làm phiền tôi một lần nữa.
Stanislav Shabalin

Vì đây là ưu tiên bash, nó có thể phá vỡ các lệnh đường ống không?
Stanislav Shabalin

1
@StanislavShabalin Điều này không ảnh hưởng đến đường ống, chỉ nhắc nhở.
Gilles 'SO- ngừng trở nên xấu xa'

Tôi cần xóa "-1" sau "COLUMNS" để nó hoạt động chính xác.
rafak

Giải pháp này khiến cho dấu nhắc di chuyển khi cửa sổ đầu cuối bị thay đổi kích thước. Tôi thấy rằng để thực hiện công việc này một cách đáng tin cậy, tôi phải lấy cột hiện tại PROMPT_COMMANDvà nếu không phải là 0, hãy sử dụng một dòng mới ( \n) làm ký tự đầu tiên của PS1.
Brian Donovan

10

Tôi thích phương pháp sau ...

cat example.txt ; echo

Điều này không đánh giá nội dung example.txthoặc đôi khi thêm một dòng mới. Nó chỉ lặp lại một dòng mới sau khi con mèo được thực hiện, rất dễ nhớ và không ai nghĩ về việc họ sử dụng trích dẫn mạnh hay yếu một cách chính xác.

Nhược điểm duy nhất, thực sự, là bạn sẽ có thêm một dòng mới nếu tệp có dòng mới theo dõi riêng.


7

Tôi bắt đầu sử dụng câu trả lời của @ Gilles, nhưng thấy rằng nếu thiết bị đầu cuối thay đổi số lượng cột, dấu nhắc sẽ không còn ở đầu dòng như mong đợi. Điều này có thể xảy ra vì nhiều lý do, bao gồm chia tách tmux / màn hình, thay đổi kích thước thủ công của bộ chứa GUI, thay đổi phông chữ, v.v.

Những gì tôi thực sự muốn là một cái gì đó sẽ thêm một dòng mới nếu thiết bị đầu cuối sẽ bắt đầu in dấu nhắc của nó tại một cái gì đó không phải là cột đầu tiên. Để làm điều này tôi cần phải tìm ra cách lấy cột hiện tại, mà tôi đã sử dụng câu trả lời này để có được. Cấu hình nhắc nhở làm việc cuối cùng là dưới đây:

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

Tôi sử dụng giải pháp này, nhưng khi tôi cố gắng dán các lệnh nhiều dòng vào vỏ của mình, nó dường như đã kết thúc việc ăn một phần / tất cả các dòng sau khi lần đầu tiên dán. Có giải pháp nào cho việc này không?
chỉ

@onlynone có thể các lệnh của bạn không được xóa riêng lẻ và kịp thời __get_terminal_column?
Androbin

Thay vì PS1="\n"tôi chỉ có echovà không cần phải sửa đổi PS1.
Androbin

4

Vấn đề với điều đó có thể là example.txt của bạn không có dòng mới ở cuối tệp.


2
Vấn đề là tôi không quan tâm liệu tập tin có dòng mới ở cuối hay không. Tôi muốn có thể thấy đầu ra của mèo rõ ràng hơn và không gây khó chịu này :-) Và tôi hiểu đó không phải catlà công việc nên có lẽ tôi đang tìm cách giải quyết.
Stanislav Shabalin

1
Đây là một câu trả lời example.txtkhông có dòng mới ở cuối tập tin là toàn bộ điểm của câu hỏi.
Willem D'Haeseleer

2

Nếu bạn khăng khăng sử dụng cat, điều này hoạt động cho cả hai loại tệp, có và không có dòng mới ở cuối:

echo "`cat example.txt`"

Bạn có thể biến nó thành một hàm với tên bạn chọn (chẵn cat) trong .bashrc:

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

1
Bây giờ điều đó là quá nhiều, ngay cả khi nó hoạt động ;-) Cảm ơn mặc dù!
Stanislav Shabalin

0

bạn cũng có thể thêm vào .bashrc

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

làm việc cho tôi


1
Điều này cũng sẽ thêm một dòng trống bổ sung trong thiết bị đầu cuối bất cứ khi nào một tiện ích xuất ra một cái gì đó được kết thúc chính xác bởi một dòng mới.
Kusalananda

Điều đó đúng. Nhưng rất đơn giản và nếu điều đó không làm phiền bạn để có thêm một dòng ...
klaus
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.