【问题标题】:bash nested read with confirmationbash 嵌套读取并确认
【发布时间】:2019-02-06 23:34:10
【问题描述】:

我正在尝试遍历来自 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。我尝试将来自test1 的FD 重定向组合到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
[~]$

【问题讨论】:

  • 如果您向我们展示一些输入和输出,那就太好了。

标签: bash


【解决方案1】:

done 3&lt;&amp;0 &lt;&lt;&lt; $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,但您不需要同时使用关键字和括号。

【讨论】:

  • 有一些关于 herestring 到重定向的 stdin 的东西,只是不太正确......
【解决方案2】:

/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
}

【讨论】:

  • 这很有趣!我能看到的唯一潜在缺点是我无法使用yes 或其他东西来自动化第二个read。我喜欢不必使用 FD 恶作剧。
【解决方案3】:

你可以试试

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

附:抱歉,格式这么差,我到电脑后会更新它

【讨论】:

  • 谢谢! for 的问题在于它遍历每个空格分隔的标记,而不是每一行。我可以通过将 IFS 设置为 ' ' 以外的其他值来解决这个问题,但我认为这会打乱我的第二次阅读。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-16
相关资源
最近更新 更多