【问题标题】:User input line by line by hit enter用户输入逐行按回车
【发布时间】:2021-12-29 20:25:28
【问题描述】:

我想制作一个脚本,当用户输入无穷无尽的新行(回车)并且当他点击点(。)然后输入时,它将把他的列表标准输出到文件中。 就像“mailx -s”命令。

例如:

Enter names (hit dot (".") to interrupt) :
name1
name2
name3
name4
and so on

.
EOF

我尝试了以下方法:

read -rp 'Please enter the details: ' -d $'\04' data
declare -p data

现有代码是ctrl+D, 我需要的是 dot 作为文件的现有代码。

提前致谢。

【问题讨论】:

  • $'\04' 替换为.
  • @Cyrus。这很诱人,但在输入 . 时会失败,而 . 本身并不在一行中。

标签: bash shell


【解决方案1】:

我会稍微修改一下 William Pursell 的答案,因为您不妨读入一个数组,而不是每次都覆盖相同的字符串(即 O(n^2)):

#!/bin/bash

# or use echo if you want the prompt on a separate line
printf 'Please enter the details: '

lines=()
while IFS= read -r line && [[ "$line" != . ]]; do
  lines+=("${line}")
done

printf '%s\n' "${lines[@]}"

如果您还没有看到https://mywiki.wooledge.org/BashFAQ/001,请参阅IFS=-r。您可能不想要IFS=,具体取决于您的具体要求。

【讨论】:

  • 并注意-r 的影响。作为用户,我通常希望能够应用转义序列,并且我希望它们能够得到尊重。如果您使用-r 读取输入,则会阻止正常的交互使用。续行是一个重要的特性,不应该被大肆丢弃。
  • 虽然我同意它有它的用途,但 IMO 转义序列解析应该是人们在需要时选择加入的东西,不幸的是 read 使它成为默认行为。如果默认值被翻转,我们甚至不必讨论这种行为,因为需要它的人只需在需要时传递“解析转义序列”标志并完成它:)
【解决方案2】:

不要试图一口气读完。循环并检查每一行。比如:

#!/bin/sh

content=
while read line && test "$line" != . ; do
        content="${content}${line}
"
done

printf "%s" "$content"

【讨论】:

  • 同意循环阅读,但也可以使用-r和(通常)IFS= - mywiki.wooledge.org/BashFAQ/001
  • @dimo414 我完全不同意-r 的泛滥使用。通常情况下,不应将转义的换行符视为终止输入的原始转义字符,而盲目地应用 -r 是错误的。当只有一个变量时,取消设置 IFS 是没有意义的,如果读取了多个变量,那么取消设置 IFS 可能不是所需的行为。在不了解影响的情况下盲目遵循该食谱是错误的。
猜你喜欢
  • 1970-01-01
  • 2011-07-12
  • 2020-03-18
  • 1970-01-01
  • 2018-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多