一般的な問題
パイプのチェーンの途中であっても、ユーザーと対話するスクリプトを記述したいと思います。
具体例
具体的には、file
またはを受け取り、stdin
行(行番号付き)を表示し、選択範囲または行番号の入力をユーザーに要求し、対応する行をに出力しstdout
ます。このスクリプトを呼び出しましょうselector
。それから基本的に、私はできるようになりたいです
grep abc foo | selector > myfile.tmp
foo
含む場合
blabcbla
foo abc bar
quux
xyzzy abc
次に、selector
(ターミナルではなく、myfile.tmp
!)オプションを表示します
1) blabcbla
2) foo abc bar
3) xyzzy abc
Select options:
その後入力します
2-3
そして結局
foo abc bar
xyzzy abc
の内容としてmyfile.tmp
。
私はセレクタースクリプトを起動して実行しています。入力と出力をリダイレクトしなければ、基本的には完全に機能しています。そう
selector foo
私が望むように動作します。ただし、上記の例のように物事を一緒にパイプする場合、selector
は提示されたオプションをに出力myfile.tmp
し、grepped入力から選択を読み取ろうとします。
私のアプローチ
次のように、の-u
フラグを使用しようとしましread
た
exec 4< /proc/$PPID/fd/0
exec 4> /proc/$PPID/fd/1
nl $INPUT >4
read -u4 -p"Select options: "
しかし、これは私が望んでいたことをしません。
Q:実際のユーザーインタラクションを取得するにはどうすればよいですか?
cmd | { some processing; read var </dev/tty; } | cmd
alias selector='{ TMPFILE=$(mktemp); cat > $TMPFILE; nl -s") " $TMPFILE | column -c $(tput cols); read -e -p"Select options: " < /dev/tty; rangeselect -v range="$REPLY" $TMPFILE; rm $TMPFILE; }'
どれがかなりうまくいくかを持っています。ただしgrep b foo | selector | wc -l
、ここで中断します。それを修正する方法はありますか?ちなみに、rangeselect
私が使用したものはpastebin.com/VAxTSSHsにあります。これは、指定された範囲の行番号に対応するファイルの行を出力する単純なAWKスクリプトです。(範囲は「3-10、12、14、16-20」のようなものにすることができます。)
alias
ということを、selector() { all of that stuff...; }
関数に。alias
esは単純なコマンドの名前を変更しますが、関数は複合コマンドを単一の単純なコマンドにパックします。