运行时过滤脚本输出

运行时过滤脚本输出

我有一个脚本,它在后台运行大约 10 个其他脚本,不断生成新的输出。我希望保持初始脚本运行,并且能够简单地输入它以过滤实时显示在终端上的所有输出。

为了简单起见,假设每个 for 循环都代表我的后台脚本之一(顺便说一句,输出包含颜色代码。):

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",但我不想在最终输出中丢失颜色,所以这并不容易。

输入消失问题:即使我在按回车键进行搜索后设法实时打印新的输出,用户也无法正确键入(或查看,更准确地说)他/她的下一个搜索。我希望用户输入的过滤文本始终可见。

有什么想法可以实现这一点吗?

答案1

less -R

您可以使用查看less

  • 使用选项查看 ANSI 颜色-R
  • 向前搜索patternwith/pattern
  • 向后搜索patternwith?pattern

  • 使用arrow键 和PgUpPgDnHome、进行导航End


  • 请注意,当您按下该键时,您的缓冲区已更新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和 的Shell 脚本grep

简单less命令的替代方案是以下小 shell 脚本。它假设您可以在终端窗口中滚动足够多的内容来查看旧的输出。如果缓冲区不够大,可以增加缓冲区。我的“.bashrc”中有以下几行,我认为它们为此目的做了您想要的事情,

HISTFILESIZE=1000000
HISTSIZE=10000

用于过滤和检查的 Shellscript,

#!/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

请注意,此 shellscript 还将看到 ANSI 转义序列,因此,例如,如果您想过滤0,您将看到所有行(因为重置序列中有一个零)。您可以使用扩展正则表达式(其中-E的选项grep可以指定您要搜索的内容,例如\ .?00$.

(这不是问题less -R)。

相关内容