実行時のスクリプト出力のフィルタリング

実行時のスクリプト出力のフィルタリング

バックグラウンドで約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

fifotailおよびを含むシェルスクリプト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\ .?00$

(これは問題ではありませんless -R)。

関連情報