之前的bash循环迭代到下一个迭代的输出,用于各种grep命令 [英] Output of previous bash loop iteration into next iteration for varying grep commands

查看:125
本文介绍了之前的bash循环迭代到下一个迭代的输出,用于各种grep命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从一个for循环的一个迭代中获取grep命令的输出,并在下一个迭代中将其转换为下一个grep命令的输入.

I'm in a situation where I'm wanting to take the output of a grep command from one iteration of a for-loop and turn it into the input for the next grep command in the following iteration.

通常,我将使用数组和for循环来构建单个grep命令,但是,因为我需要bash变量GREP_COLOR在两次迭代之间进行更改,所以我遇到了这个问题.我想我可以创建三个不同的函数,除了那个变量外,它们都做同样的事情,但是如果可能的话,我宁愿有一个单一的函数.这是数组:

Normally, I would use an array and the for-loop to build a single grep command, however because I need the bash variable GREP_COLOR to change between iterations I'm running into this issue. I suppose I could make three different functions that all do the same thing except for that variable, but I'd prefer to have a single function if at all possible. Here's the array:

patterns=("general-red" "general-yellow" "general-green" "ha-red" "ha-yellow" "ha-green")

功能如下:

function iterate-patterns() {
    for i in "${patterns[@]}"
    do
            if [[ "$i" = *-red ]]
            then
                    GREP_COLOR="$RED" grep -E --text --color=always --line-buffered -f /var/lib/foobar/"${i}".txt
            elif [[ "$i" = *-yellow ]]
            then
                    GREP_COLOR="$YELLOW" grep -E --text --color=always --line-buffered -f /var/lib/foobar/"${i}".txt
            elif [[ "$i" = *-green ]]
            then
                    GREP_COLOR="$GREEN" grep -E --text --color=always --line-buffered -f /var/lib/foobar/"${i}".txt 
            else
                    cat 
            fi
    done
}

这是调用该函数的函数,提供初始输入:

Here's the function that calls that function, providing the initial input:

function daddyfunction() {

    iterate-filters |\
    iterate-experimental |\
    iterate-patterns 
}

本质上,数组中的每个项目都代表grep -f命令的文件,该文件具有许多要搜索的图案并以所需的颜色突出显示.但是,按照当前的代码显示,只有第一个数组项最终被显示.我可以肯定地说是因为每个grep需要以某种方式更改为以下迭代的grep命令的输入.

Essentially, each item in the array represents a file for the grep -f command with many patterns to be searched for and highlighted with the desired color. However, as the code currently stands, only the first array item ends up being displayed. This I'm fairly certain is because each grep needs to be somehow changed into input for the following iteration's grep command.

这可行吗?我会为每种颜色制作函数吗?有没有更好的方法来完成所有这些工作?我寻求互联网的智慧. ;)请,谢谢.

Is this do-able? Am I stuck making a function for each color? Is there a better way to accomplish all this? I seek the wisdom of the internets. ;) Please and thank you.

仅需确认,三个独立的功能确实起作用:

Just to confirm, three separate functions does work:

function iterate-redhighlights() {
    greplist=()
    for i in "${redpatterns[@]}"
    do
            if [[ "$i" = *-red ]]
            then
                    greplist+=( -f /var/lib/foobar/"${i}".txt)
            else
                    cat
            fi
    done
    GREP_COLOR="$RED" $search "${greplist[@]}"
}
function iterate-yellowhighlights() {
    greplist=()
    for i in "${yellowpatterns[@]}"
    do
            if [[ "$i" = *-yellow ]]
            then
                    greplist+=( -f /var/lib/foobar/"${i}".txt)
            else
                    cat
            fi
    done
    GREP_COLOR="$YELLOW" $search "${greplist[@]}"
}
function iterate-greenhighlights() {
    greplist=()
    for i in "${greenpatterns[@]}"
    do
            if [[ "$i" = *-green ]]
            then
                    greplist+=( -f /var/lib/foobar/"${i}".txt)
            else
                    cat
            fi
    done
    GREP_COLOR="$GREEN" $search "${greplist[@]}"
}

推荐答案

stdin中读取grep时,您不能在循环中运行它.第一次迭代将读取stdin的所有内容,并且无法退回到下一个迭代的开始(文件支持查找,但管道不支持查找,并且没有shell语法可以做到).

You can't run grep in a loop when it's reading from stdin. The first iteration will read all of stdin, and there's no way to rewind back to the beginning for the next iteration (files support seeking, but pipes don't, and there's no shell syntax to do it).

您可以在循环之前将所有stdin复制到一个临时文件,然后每次处理该文件.将输出重定向到另一个临时文件,然后将其复制回输入文件以准备下一次迭代.

You can copy all of stdin to a temporary file before the loop and then process that file each time. Redirect the output to another temporary file, then copy that back over the input file to prepare for the next iteration.

iterate-patterns() {
    tempfile=$(mktemp /tmp/patterns.XXXXXX)
    tempfile2=$(mktemp /tmp/patterns2.XXXXXX)
    cat > "$tempfile"
    for i in "${patterns[@]}"
    do
        if [[ "$i" = *-red ]]
        then
            GREP_COLOR="$RED" grep -E --text --color=always --line-buffered -f /var/lib/foobar/"${i}".txt "$tempfile" > "$tempfile2"
        elif [[ "$i" = *-yellow ]]
        then
            GREP_COLOR="$YELLOW" grep -E --text --color=always --line-buffered -f /var/lib/foobar/"${i}".txt "$tempfile" > "$tempfile2"
        elif [[ "$i" = *-green ]]
        then
            GREP_COLOR="$GREEN" grep -E --text --color=always --line-buffered -f /var/lib/foobar/"${i}".txt "$tempfile" > "$tempfile2"
        else
            cat "$tempfile" > "$tempfile2"
        fi
        cp "$tempfile2" "$tempfile"
    done
    cat "$tempfile"
    rm "$tempfile" "$tempfile2"
}

这篇关于之前的bash循环迭代到下一个迭代的输出,用于各种grep命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆