文字列を文字単位で読み取って処理しますが、ユーザーが入力に対して簡単な行編集を実行できるようにします。

文字列を文字単位で読み取って処理しますが、ユーザーが入力に対して簡単な行編集を実行できるようにします。

端末から入力行を徐々に読み、ユーザーにINS、DEL、右、左、終了、バックスペース機能を許可したいと思います。

文字列が変更されるたびにそれを処理して、テキストファイルに対して増分正規表現検索を実行したいと思います。

これらの編集キーと他のキーは複数の入力文字を生成するため、
入力を解釈するのは非常に困難です。たとえば、C-Leftは6文字を生成します。

文字ごとに編集可能な入力を簡単に取得する方法はありますか?
残りの処理はbashで行われるので、bashでこれを行う方法を知りたいです。他の提案も歓迎します。

それで始めましたが、潜在的な制御コードが多すぎて少し余裕がありませんでした。

#!/bin/bash
IFS=$'\n' 
while true ;do
  read -n 1 c
  ((${#c}==0)) && break # Exit the loop. Input length is 0  
                        # ie. The user has pressed Enter
  echo "xx=$(echo -n "$c"|xxd -p)="
  # 1b 5b 32 7e  "INS"
  # 1b 5b 33 7e  "DEL"
  # 1b 5b 43     "RIGHT"
  # 1b 5b 44     "LEFT"
  # 1b 5b 46     "END"
  # 1b 5b 48     "HOME"
  # 7f           "BACKSPACE"
done

答え1

一度に1文字ずつ読み込む場合は、read -nキーシーケンスパーサを実装する必要があります。以下を使用して、ほとんどの端末で動作する遅くて汚れたソリューションを構築できます。エスケープ文字で始まり、任意の数の文字で続くファンクションキーエスケープシーケンスを考慮して、この文字セットにない0-9;[]O最後の文字が続きます。

入力を読み取るより良い方法は、適切な入力ライブラリを使用することです。 Bashはこれを独自の目的に使用します(読書船)。組み込みを使用してbind独自のキーバインディングを宣言すると、bind -xキーを押したときにシェルコマンドを実行するように特別に設計された制限付きインターフェイスを取得できます。制限されたインターフェイスのために、必要なものを実装することは可能かもしれませんが、難しいです。

Zshには独自の入力ライブラリがあります。ズラー。インターフェイスはbashよりはるかに豊富です。 zleを使用すると、任意のキーマップを定義でき、シェルコードからzleの内部機能にアクセスできます。zleカスタムコマンド(ウィジェットと呼ばれる)にシェル機能を割り当て、bindkey独自のキーマップを作成および入力し、最後にvared選択したキーマップを使用して入力行を読み取るために使用されます。

答え2

read文字がある場合は、最初の端末の後に端末をネイティブモードに設定してから、2番目の端末を使用して残りのバイトescread存在する場合)を読み取って解析できます(参照)。BASHはキャラクタートラウマから抜け出した。また見てください矢印.txt)。

#!/bin/bash

# tested on Mac OS X 10.6.8

IFS=$'\n'
old_tty_settings="$(stty -g)"
exec 0</dev/tty

tput smir  # enable insert mode

while IFS="" read -r -s -n1 key; do    # first read (reads only a single byte)

#od -c <<<"$key"
#continue

((${#key}==0)) && break

case "$key" in
  $'\001')  printf '\r'                          #  ctrl-a
            continue;;   
  $'\177')  tput rmir 
            printf "\010\040\010\033[P"          # backspace
            tput smir
            continue;;                          
  $'\025')  printf "\033[1K"                     # tput el1 does not work on Mac OS X 10.6.8 
            continue;;                           # ctrl-u  (clear to start of line)
  $'\v')    tput el
            continue;;                           # ctrl-k  (clear to end of line)
esac

# if the first char is esc (i.e. \e or \033 respectively)
if [[ "$key" == $'\033' ]]; then    

  stty cbreak -echo min 0 time 0   # set raw terminal 

  IFS="" read -r bytes     # second read (reads remaining bytes)

  if [[ ${#bytes} -gt 0 ]]; then

     stty "$old_tty_settings"

     case "${key}${bytes}" in 
       $'\033[3~')   tput dch1         # delete one char
                     continue;; 
     esac

     printf "${key}${bytes}"

  else
     stty "$old_tty_settings"
  fi

 else

  #stty "$old_tty_settings"
  printf '%s' "$key"

fi

done

echo

exit 0

答え3

コマンドラインツールを見るセレクタ

# usage examples
selector -v -x @ <(find . -maxdepth 2 -type d | awk '{print $0"@cd "$0}')
selector -v -x @ <(grep -E -o 'http[^ ]+' fileWithURLS)

答え4

スクリプトを使用せずにbash組み込み機能のみを使用してください。

read -e INPUT  # single line

INPUT=$(</dev/stdin)  # multiple lines

源泉)

または、leditパッケージをインストールしたら、次のものを使用できます。

INPUT=$(ledit)

関連情報