バックグラウンドで約10の異なるスクリプトを実行して、常に新しい出力を生成するスクリプトがあります。初期スクリプトを実行し続け、それを入力して、端末に表示されるすべての出力をリアルタイムでフィルタリングしたいと思います。
簡単にするために、各forループがバックグラウンドスクリプトの1つを表すとします(出力にはカラーコードが含まれています)。
for i in {0..1000} ; do
echo -e "\033[0;31mHello world\033[0m $i"
sleep 1
done &
for i in {0..1000} ; do
echo -e "\033[0;34mHello world\033[0m $i"
sleep 1
done &
私の最初のアイデアは、バックグラウンドスクリプトのすべての出力をファイルにリダイレクトし、コマンドを使用してread
検索クエリを取得し、次のようgrep
に渡すことでした。
for i in {0..1000} ; do
echo -e "\033[0;31mHello world\033[0m $i"
sleep 1
done >> ./output.txt 2>&1 &
for j in {0..1000} ; do
echo -e "\033[0;34mHello world\033[0m $j"
sleep 1
done >> ./output.txt 2>&1 &
while true ; do
read -p "Search: " query
clear
cat ./output.txt | grep "$query"
done
しかし、いくつかの問題があります。
質問の更新:ファイルが変更されても出力は更新されませんoutput.txt
。したがって、最新の結果を得るには、引き続き検索する必要があります。
カラーコードの問題:検索すると、3
カラーコードに含まれるすべての行が印刷されます3
。もちろん、次のように色を完全にフィルタリングできますが、cat ./output.txt | sed 's/\x1b\[[0-9;]*m//g' | grep "$query"
最終出力で色を失いたくないので簡単ではありません。
入力が消える問題:検索のためにEnterキーを押した後、リアルタイムで新しい出力を印刷しても、ユーザーは次のクエリを正しく入力することができません(より正確には表示されません)。ユーザーが入力したフィルタ処理されたテキストが常に表示されるようにしたいと思います。
これを達成する方法についてのアイデアはありますか?
答え1
less -R
less
ビューアを利用できます
- オプションを使用したANSIカラーの表示
-R
- 今後検索
pattern
する/pattern
pattern
次へ戻る?pattern
ナビゲートするには、キーarrowと、、を使用します。PgUpPgDnHomeEnd
- キーを押すとバッファが更新されますEnd。 :-)
- カラーコーディングの問題を修正しました。
- 入力は消えません。
次のスクリプトを使用して作成します。
#!/bin/bash
for i in {0..1000} ; do
echo -e "\033[0;31mHello world\033[0m $i"
sleep 1
done >> output.txt 2>&1 &
for j in {0..1000} ; do
echo -e "\033[0;34mHello world\033[0m $j"
sleep 1
done >> output.txt 2>&1 &
読み取り/確認するには、このコマンドラインを使用してください。
less -R output.txt
fifo
、tail
およびを含むシェルスクリプトgrep
単純なコマンドless
の代替は、次の小さなシェルスクリプトです。これは、ターミナルウィンドウで前の出力を見るのに十分なスクロールが可能であると仮定します。バッファが十分に大きくない場合は、バッファを増やすことができます。私の ".bashrc"には、この目的のために好きなようにできる次の行があります。
HISTFILESIZE=1000000
HISTSIZE=10000
フィルタリングと検査のためのシェルスクリプト、
#!/bin/bash
# this function is called when Ctrl-C is sent ##########################
inversvid="\0033[7m"
resetvid="\0033[0m"
function trap_ctrlc ()
{
# perform cleanup here
echo " Press <Enter> to continue with another query or"
echo -en "$inversvid"
read -s -n1 -t5 -p " <x> to exit " ans
echo -en "$resetvid"
if [ "$ans" == "x" ]
then
# exit shell script
# if omitted, shell script will continue execution
echo ""
exit
else
echo ""
fi
}
##### main #############################################################
# initialise trap to call trap_ctrlc function
# when signal 2 (SIGINT) is received
trap "trap_ctrlc" 2
echo "Scroll the terminal window (maybe inscrease the buffer to store enough lines)
Interrupt viewing the filtered output with <ctrl c>"
if [ "$1" == "" ]
then
read -p "Search: " query
else
query="$@"
fi
# create fifo
mkfifo fifo
# run a loop for queries and filtered output
while true ; do
if [ "$query" == "" ]
then
read -p "New search: " query
fi
# mkfifo fifo
clear
tail -n 10000 -f output.txt > fifo &
grep --color -E "$query" fifo
sleep 0.1
query=""
done
このシェルスクリプトはANSIエスケープシーケンスも表示できるため、たとえばフィルタリングしたい場合はすべての0
行を表示できます(リセットシーケンスにゼロがあるため)。代わりに、検索する項目を指定する-E
オプションとともに拡張正規表現を使用できます。grep
\ .?0
0$
(これは問題ではありませんless -R
)。