【问题标题】:How do i stop the readarray prompt using a specific keyword?如何使用特定关键字停止 readarray 提示?
【发布时间】:2020-11-28 19:20:16
【问题描述】:
#!/bin/bash
tty=$(readlink /proc/$$/fd/2)

echo "Paste Content below"
readarray -d '\n' lines < $tty
printf '%s\n' "${lines[@]}" > links.txt

所以我使用上面的脚本将文本块存储在变量 lines 中并将其写入文件 links.txt 。 问题是当 readarray 提示出现并粘贴我的文本时,我必须通过执行 ctrl + d 来停止读取过程,然后脚本继续进行并将存储的变量写入 links.txt

理想情况下,我希望某个特定关键字充当我粘贴的端点,一旦检测到该特定单词,阅读提示就会自动结束 例如,在我粘贴了我的内容之后。如果我在新行上输入stopread,它应该停止读取过程并继续执行脚本 (我刚刚以stopread这个词为例)

示例 - 在 readarray 提示符下,如果我粘贴

1
2
3
stopread

它应该将 1 ..3 存储在变量 lines 中并在脚本中继续进行,而无需执行 ctrl + d 来停止关闭读取提示

【问题讨论】:

  • readarray 之后是否还有其他从标准输入读取的命令(例如提示用户输入)?
  • 那么这里就有问题了。您不能可靠地丢弃stopread 之后的行,存储单行输出 的命令将读取紧随stopread 之后的行。试试readarray lines &lt; &lt;(sed '/stopread/q' /dev/tty),看看它是如何失败的。
  • @oguzismail 是的,下面还有一个读取命令(不是 readarray),它存储单行输出,所以只需按 Enter 就可以完成读取工作。我也在编写 readarray 和 read到 tty ,你可能还记得,我没有在这里添加它,因为它不是主要关注点,所以我保持代码尽可能简单
  • 你需要一个循环,而不是readarray/mapfile。
  • 而且文件描述符 2 是标准的错误。 0 是 input 和你应该阅读的内容。

标签: linux bash unix awk sed


【解决方案1】:

您应该使用while read 循环来执行此操作,因为这将只允许您读取必要的数据而不再读取(由于缓冲区大小为 1),从而允许脚本的其余部分消耗其余部分以稳健的方式输入:

lines=()
while IFS= read -r line && [[ "$line" != "stopread" ]]
do
  lines+=("$line")
done

但是,既然你问怎么做readarray,你可以这样做:

readarray -d '\n' lines < <(sed '/stopread/q')

这本质上会读取更大的缓冲区大小,因此可能会过度消耗输入。例如,如果停用词出现在缓冲区的一半,则缓冲区的其余部分必然被丢弃。它甚至比脆弱和不可预测更糟糕,因为您无法在典型的人工输入速度下的随意测试中发现任何问题,因此可能更容易被愚弄,认为这是一个好的解决方案。

【讨论】:

  • 非常感谢您对 while 循环的解释和推荐,我测试了这两个解决方案,并且 while 循环解决方案完美运行。就我个人而言,我的目的已达到,我将使用 while 循环解决方案,尽管对于观众在这篇文章中,也许您可​​以调试 readarray 解决方案,目前它有 2 个小问题 1) 如果我使用 tty - readarray -d '\n' lines
  • readarray -d '\n' lines &lt; &lt;(sed '/stopread/q') 填充lines[0] 之前的所有输入行,包括stopread 及其后的换行符。 ITYM 使用$'\n' 而不是\n' 作为分隔符,但在lines[] 中仍包括stopread。我无法想象为什么添加 &lt; $tty 会产生任何影响,但无论如何这些都不是必需的。
【解决方案2】:

就像在your previous question 中一样,数组对于您正在尝试做的事情没有用处:

$ foo=$(awk '/stopread/{exit} 1' file)
$ echo "$foo"
1
2
3

或从标准输入读取:

$ foo=$(awk '/stopread/{exit} 1')
1
2
3
stopread
$ echo "$foo"
1
2
3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多