以下のように動作する「選択」フィルタスクリプトを教えてくれる人はいますか?
私は値のリストをパイプで接続し、コンソールで選択した項目に従ってそのサブセットをエクスポートできる単純なbashスクリプト/フィルタを見つけるのに約1時間かかりました。私はCで書かれた例があることを知っていますが、Cygwin / Gitbashなどで利用可能なほとんどの移植可能なbashスクリプトが欲しいです。 (コンテキスト:特定のサブディレクトリから特定のコマンドを実行できるようにしたいので、コマンドを実行したいディレクトリの選択を実行したいコマンドによって選択されたディレクトリに分割したいと思います。)
仮想の使用例は次のとおりです。
$ echo "foo
> bar
> baz" | pick.sh
* Options:
* 1. foo
* 2. bar
* 3. baz
* Choices? 2 3
bar
baz
*で示されている行は、スクリプトを介して対話式に「選択」する要素を選択できる場所で、2行と3行を決定するとSTDOUTに送信されます。
理想的には、選択はスペースで区切られた数字(2 3 4など)と包含範囲(2-4など)の組み合わせです。あるいは、アイテム自体の最初の数文字を入力することができる一種のオートコンプリート機能を使用するのと同じくらいクールです。
まあ、それはすべてです。全体的にこれは非常に便利なbashパイプフィルタになると思います!
(今まで読んでくれてありがとう。)
答え1
sed
行指定子(N,M
NからMまでの行を意味する)を使用した自己デモンストレーションの例:
$ ./pick.sh < ./pick.sh
Lines:
1 #!/usr/bin/env bash
2
3 set -o errexit -o nounset -o noclobber
4
5 trap 'rm --force --recursive "$working_directory"' EXIT
6 working_directory="$(mktemp --directory)"
7 input_file="${working_directory}/input.txt"
8
9 cat > "$input_file"
10
11 echo 'Lines:'
12 cat --number "$input_file"
13
14 IFS=' ' read -p 'Choices: ' input < /dev/tty
15 lines=($input)
16
17 sed --quiet "$(printf '%sp;' "${lines[@]}")" "$input_file"
Choices: 1 5,7 17
#!/usr/bin/env bash
trap 'rm --force --recursive "$working_directory"' EXIT
working_directory="$(mktemp --directory)"
input_file="${working_directory}/input.txt"
sed --quiet "$(printf '%sp;' "${lines[@]}")" "$input_file"
デフォルトでは、標準入力を一時ファイルに保存し、行番号でファイルを印刷し、範囲を入力するように求められ、入力範囲を渡してsed
各範囲を印刷します。
この方法の1つの珍しい点は、指定された順序ではなく、ファイルに表示される順序で行が印刷されることです。
…
Choices: 3 1
#!/usr/bin/env bash
set -o errexit -o nounset -o noclobber
入力シーケンスが本当に必要な場合は、これを繰り返すのは簡単ではありませんlines
。もちろん、これはあまり効率的ではありません。
このスクリプトはあなたが牛に似た一種の栄養 cat
などsed
が設置されました。 BSDツールを使用している場合は、コマンドフラグが異なります。