ऊर्ध्वाधर कर्सर स्थिति प्राप्त करें


10

यह बहुत अजीब लग सकता है, लेकिन मुझे पता है कि इस तरह से बैश में ऊर्ध्वाधर कर्सर स्थिति कैसे सेट करें:

echo -e "\e[12H"

यह कर्सर को 12 वीं पंक्ति (1 से शुरू) में ले जाता है।

तो मैं linash bash का उपयोग करके कर्सर स्थिति (लाइन नंबर) कैसे प्राप्त करूं? यह उपयोगी होगा यदि मैं इस मूल्य को एक चर में संग्रहीत कर सकता हूं ताकि मैं इसके साथ गणना कर सकूं।

संपादित करें:

यह मुझे मिलने वाली त्रुटि है:

$ sh rowcol.sh
-en
    read: 9: Illegal option -d
                              test.sh: 12: Bad substitution

एक उदाहरण स्क्रिप्ट भी देखें (सबसे सरल नहीं क्योंकि उस पर अतिरिक्त अड़चनें थीं)।
गिल्स एसओ- बुराई को रोकना '

जवाबों:


5

मैं एसओ पर एक ही लेख से कुछ उदाहरणों का उपयोग करने में सक्षम था, जिसका शीर्षक था: बैश में कर्सर की स्थिति कैसे प्राप्त करें? । मैं इसे यहाँ पोस्ट कर रहा हूँ बस यह दिखाने के लिए कि वे काम करते हैं और समाधान की सामग्री वास्तव में U & L पर भी है।

बैश समाधान

एक स्क्रिप्ट के अंदर से

#!/bin/bash
# based on a script from http://invisible-island.net/xterm/xterm.faq.html
exec < /dev/tty
oldstty=$(stty -g)
stty raw -echo min 0
# on my system, the following line can be replaced by the line below it
echo -en "\033[6n" > /dev/tty
# tput u7 > /dev/tty    # when TERM=xterm (and relatives)
IFS=';' read -r -d R -a pos
stty $oldstty
# change from one-based to zero based so they work with: tput cup $row $col
row=$((${pos[0]:2} - 1))    # strip off the esc-[
col=$((${pos[1]} - 1))

echo "(row,col): $row,$col"

नोट: मैंने आउटपुट को थोड़ा बदल दिया है!

उदाहरण

$ ./rowcol.bash 
(row,col): 43,0
$ clear
$ ./rowcol.bash 
(row,col): 1,0

परस्पर खोल

इस कमांड श्रृंखला ने कर्सर की पंक्ति और स्तंभ स्थिति प्राप्त करने के लिए काम किया:

$ echo -en "\E[6n";read -sdR CURPOS; CURPOS=${CURPOS#*[};echo "${CURPOS}"

उदाहरण

$ echo -en "\E[6n";read -sdR CURPOS; CURPOS=${CURPOS#*[};echo "${CURPOS}"
13;1
$ clear
$ echo -en "\E[6n";read -sdR CURPOS; CURPOS=${CURPOS#*[};echo "${CURPOS}"
2;1

नोट: यह विधि किसी भी प्रकार की लिपि से प्रयोग करने योग्य प्रतीत नहीं होती है। एक इंटरैक्टिव टर्मिनल में भी साधारण कमांड मेरे लिए काम नहीं करता था। उदाहरण के लिए:

$ pos=$(echo -en "\E[6n";read -sdR CURPOS; CURPOS=${CURPOS#*[};echo "${CURPOS}")

बस अनिश्चित काल के लिए लटका हुआ है।

पानी का छींटा / श समाधान

एक स्क्रिप्ट के अंदर से

यह समाधान उबंटू / डेबियन सिस्टम के लिए है जो स्टॉक के साथ आते हैं dash, जो कि पॉसिक्स कंप्लेंट है। इस वजह से, readकमांड -dअन्य अंतरों के बीच स्विच का समर्थन नहीं करता है ।

इसके चारों ओर जाने के लिए यह समाधान है जो स्विच के sleep 1स्थान पर उपयोग करता है -d। यह आदर्श नहीं है, लेकिन कम से कम काम कर समाधान प्रदान करता है।

#!/bin/sh

exec < /dev/tty
oldstty=$(stty -g)
stty raw -echo min 0
tput u7 > /dev/tty
sleep 1
IFS=';' read -r row col
stty $oldstty

row=$(expr $(expr substr $row 3 99) - 1)        # Strip leading escape off
col=$(expr ${col%R} - 1)                        # Strip trailing 'R' off

echo "(row,col): $col,$row"

उदाहरण

$ ./rowcol.sh 
(row,col): 0,24
$ clear
$ ./rowcol.sh 
(row,col): 0,1

परस्पर खोल

मैं एक व्यावहारिक समाधान नहीं खोज सका जो सिर्फ shएक इंटरैक्टिव शेल में काम करता है।


यह केवल काम के साथ लगता है। और श के साथ नहीं। मैं व्यक्तिगत रूप से श को प्राथमिकता देता हूं। तो मैं श के साथ इसका उपयोग कैसे कर सकता हूं?
ब्रेनस्टोन

1
@BrainStone - मुझे अनुसंधान करने दें और देखें कि क्या मुझे कोई रास्ता नहीं मिल रहा है।
स्लम

sh rowcol.sh। इससे कोई फर्क नहीं पड़ता कि आपने पहली पंक्ति ( #!/bin/bashया #!/bin/sh) में क्या डाला है या फ़ाइल का क्या अंत है!
ब्रेनस्टोन

@BrainStone - लेकिन मुझे लगता shहै कि सिर्फ एक संगतता मोड है bash। जब मैं ऐसा करता हूं ( sh rowcol.bash) यह काम करता है, तो क्या यह आपके लिए काम नहीं करता है?
slm

1
@BrainStone - आप एक उपनाम बना सकते हैं alias sh=bash,?
स्लम

17

मेरे -pबजाय विकल्प का उपयोग करने से echoस्क्रिप्ट में लटकी हुई समस्या हल हो गई। के साथ परीक्षण किया गया GNU bash, version 3.00.16(1)-release (x86_64-redhat-linux-gnu)

IFS=';' read -sdR -p $'\E[6n' ROW COL;echo "${ROW#*[}"

अंतःक्रियात्मक रूप से या स्क्रिप्ट में काम करता है:

#!/usr/bin/env bash
function pos
{
    local CURPOS
    read -sdR -p $'\E[6n' CURPOS
    CURPOS=${CURPOS#*[} # Strip decoration characters <ESC>[
    echo "${CURPOS}"    # Return position in "row;col" format
}
function row
{
    local COL
    local ROW
    IFS=';' read -sdR -p $'\E[6n' ROW COL
    echo "${ROW#*[}"
}
function col
{
    local COL
    local ROW
    IFS=';' read -sdR -p $'\E[6n' ROW COL
    echo "${COL}"
}
tput sc         # Save cursor position
tput cup 5 10   # Move to row 6 col 11
POS1=$(pos)     # Get the cursor position
ROW1=$(row)
COL1=$(col)
tput cup 25 15  # Move to row 25 col 15
POS2=$(pos)     # Get the cursor position
ROW2=$(row)
COL2=$(col)
tput rc # Restore cursor position
echo $BASH_VERSION
echo $POS1 $ROW1 $COL1
echo $POS2 $ROW2 $COL2

आउटपुट:

$। / Cursor.sh
3.00.16 (1) -release
६; ११ ६ ११
26; 16 26 16

यह बहुत अच्छा काम करता है। अफसोस की बात है, यह पृष्ठभूमि प्रक्रियाओं में काम नहीं करता है, और स्क्रीन स्क्रॉल के रूप में, सहेजे गए स्तंभ परिवर्तनों के तहत लाइन।
जोंडेपोन

4

आप ANSI CSI DSR(डिवाइस स्थिति रिपोर्ट) के माध्यम से कर्सर स्थिति प्राप्त कर सकते हैं \e[6n:। ध्यान दें कि यह आपके ANSI CSR CUP(आपके) प्रश्न में उल्लिखित प्रारूप (कर्सर स्थिति) के समान प्रारूप में देता है , हालाँकि यह प्रपत्र का अनुसरण करता है \e[n;mR(जहाँ n पंक्ति और मीटर है)।

विकिपीडिया पर ANSI एस्केप कोड का अधिक विवरण ।

किसी वैरिएबल में वैल्यू को होल्ड करने के लिए, स्टैकऑवरफ्लो पर इसका जवाब दिया गया था ।

जैसा कि पिछले उत्तर / टिप्पणी (और विकिपीडिया लेख में विस्तृत) में उल्लेख किया गया है , ये कोड हमेशा पोर्टेबल नहीं होते हैं (टर्मिनल से टर्मिनल और ओएस से ओएस तक)। मुझे अभी भी लगता है कि यह बेहतर है कि इसे शाप / शाप के साथ संभाला जाए;)


और मैं इसे एक चर में कैसे स्टोर कर सकता हूं?
ब्रेनस्टोन

मैं यह काम नहीं कर सकता। मुझे हमेशा समस्याएं आती हैं echo -e, echo -enऔर read ...। यह केवल तब होता है जब फ़ाइल में कोड मौजूद होता है! मैं वास्तव में यह नहीं समझता!
ब्रेनस्टोन

ऐसा लगता है जैसे मैंने कुछ सेटिंग तोड़ दी। echo -eपहले काम किया था, लेकिन अब ऐसा नहीं है! इसका क्या कारण हो सकता है और मैं इसे कैसे पुनर्स्थापित करूं?
ब्रेनस्टोन

2

POSIX shसिंटैक्स के साथ :

if [ -t 0 ] && [ -t 1 ]; then
  old_settings=$(stty -g) || exit
  stty -icanon -echo min 0 time 3 || exit
  printf '\033[6n'
  pos=$(dd count=1 2> /dev/null)
  pos=${pos%R*}
  pos=${pos##*\[}
  x=${pos##*;} y=${pos%%;*}
  stty "$old_settings"
fi
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.