bash嵌套读取并确认

时间:2019-02-06 23:34:11

标签: bash

我试图遍历grep的每一行输出,并根据交互式提示有条件地执行某些操作。

我看过这些: Iterating over each line of ls -l output

bash: nested interactive read within a loop that's also using read

Does bash support doing a read nested within a read loop?

但是我仍然无法实现自己想要的。我认为关键的区别在于,大多数示例都是从文件读取输入-我想使用命令。我已经尝试了以下几种方法:

#! /bin/bash                                                                        

function test1()                                                                    
{                                                                                   
    local out=$(grep -n -a --color=always "target" file.txt)                                             
    while read -u 3 line; do                                                        
        echo -e "$line"                                                             
        read -r -p "ok? " response                                                  
        echo "you said: $response"                                                  
        if [[ "$response" == 'n' ]]; then                                           
            return                                                                  
        fi                                                                          
    done 3<&0 <<< $out                                                              
}                                                                                   

function test2()                                                                    
{                                                                                   
    grep -n -a --color=always "target" file.txt | while read line; do                                    
        echo -e "$line"                                                             
        read -r -p "ok? " response                                                  
        echo "you said: $response"                                                  
        if [[ "$response" == 'n' ]]; then                                           
            return                                                                  
        fi                                                                          
    done
 }  

test1()中,FD重定向似乎没有执行我想要的操作。 test2()似乎(毫不奇怪)在我的第二个read中了脚。我认为这是因为我需要切换使用中的FD。我尝试将FD重定向从test1组合到test2中,但是我无法使它与管道一起使用。我正在使用bash 4.4版。我想念什么?

这是上面两个功能的运行示例:

[~]$ cat file.txt
ksdjfklj target alsdfjaksjf alskdfj asdf asddd

alsdfjlkasjfklasj
asdf
asdfasdfs
target
assjlsadlkfjakls target
target aldkfjalsjdf
[~]$
[~]$ test1
you said: 1:ksdjfklj target alsdfjaksjf alskdfj asdf asddd 6:target 7:assjlsadlkfjakls target 8:target aldkfjalsjdf
you said:
you said:
you said:
you said:
^C
[~]$
[~]$
[~]$ test2
1:ksdjfklj target alsdfjaksjf alskdfj asdf asddd
you said: 6:target
7:assjlsadlkfjakls target
you said: 8:target aldkfjalsjdf
[~]$

3 个答案:

答案 0 :(得分:2)

done 3<&0 <<< $out很酷。换成process substitution呢?

test1() {
    while IFS= read -r -u 3 line; do
        printf '%s' "$line"
        read -r -p "ok? " response
        echo "you said: $response"
        [[ "$response" == [nN]* ]] && return
    done 3< <(
        grep -n -a --color=always "target" file.txt
    )
}

IFS= read -r是抓紧逐字记录的习惯用法。

在bash中,您可以使用funcname()function funcname,但不需要关键字和括号。

答案 1 :(得分:1)

/dev/tty读取也应该起作用

test2() {
    grep -n -a --color=always "target" file.txt | \
    while IFS= read -r line; do
        printf '%s' "$line"
        read -r -p "ok? " response </dev/tty
        echo "you said: $response"
        [[ "$response" == [nN]* ]] && return
    done
}

答案 2 :(得分:0)

您可以尝试

for line in $(grep ...); do
    echo "$line"
    read ...
    # the rest as in your functions
done

P.S。很抱歉,格式设置不正确,我将在计算机上对其进行更新