9

我对以下情况感到困惑。

我有一个文件 list.txt,我想在 bash 中逐行、循环运行。list.txt 中的典型行中有空格。问题是循环包含“读取”命令。我想用 bash 而不是 perl 之类的东西来编写这个循环。我做不到:-(

以下是我通常会编写一个循环以逐行读取文件的方式:

while read p; do
  echo $p
  echo "Hit enter for the next one."
  read x
done < list.txt

但这不起作用,因为当然“读取 x”将从 list.txt 而不是键盘读取。

这也不起作用:

for i in `cat list.txt`; do
    echo $i
    echo "Hit enter for the next one."
  read x
done

因为 list.txt 中的行中有空格。

我有两个建议的解决方案,这两个都很臭:

1)我可以编辑 list.txt,并用 "THERE_SHOULD_BE_A_SPACE_HERE" 全局替换所有空格。然后,我可以在循环中使用 sed 之类的东西将 THERE_SHOULD_BE_A_SPACE_HERE 替换为空格,这样我就准备好了。我不喜欢这个愚蠢的原因,如果 list.txt 中的任何行包含短语 THERE_SHOULD_BE_A_SPACE_HERE 它将失败(所以恶意用户可以搞砸我)。

2)我可以将while循环与stdin一起使用,然后在每个循环中我实际上可以启动例如一个新终端,这将不受原始shell中涉及stdin的事情的影响。我试过这个,我确实让它工作了,但它很丑:我想把所有这些都包装在一个 shell 脚本中,我不希望那个 shell 脚本随机打开新窗口。如果我能弄清楚如何以某种方式在命令中调用一个新的 shell 并向它提供命令而不向它提供标准输入,那么什么会很好,并且可能以某种方式回答这个问题,但我无法得到它工作。例如这不起作用,我真的不知道为什么:

while read p; do 
  bash -c "echo $p; echo ""Press enter for the next one.""; read x;"; 
done < list.txt

这种尝试似乎失败了,因为“读取 x”尽管以某种方式位于不同的 shell 中,但似乎仍在从 list.txt 读取。但我觉得我可能和这个很接近——谁知道呢。

帮助!

4

3 回答 3

15

您必须以不同的文件描述符打开

while read p <&3; do
    echo "$p"
    echo 'Hit enter for the next one'
    read x
done 3< list.txt

更新:请忽略下面评论中的冗长讨论。它与问题或这个答案无关。

于 2013-11-01T13:26:14.530 回答
1

我可能会计算文件中的行数并使用例如迭代每个行。赛德。也可以通过将 while 条件更改为:从stdin无限读取并使用ctrl+cwhile true;退出读取。

line=0 lines=$(sed -n '$=' in.file)
while [ $line -lt $lines ]
do
    let line++
    sed -n "${line}p" in.file
    echo "Hit enter for the next ${line} of ${lines}."
    read -s x
done

AWK 也是很好的工具。遍历输入的简单方法如下:

awk '{ print  $0; printf "%s", "Hit enter for the next"; getline < "-" }' file
于 2014-03-12T21:14:40.150 回答
0

作为替代方案,您可以从 stderr 读取,默认情况下它也连接到 tty。下面还包括对该假设的测试:

(
tty -s <& 2|| exit 1
while read -r line; do
    echo "$line"
    echo 'Hit enter'
    read x <& 2
done < file
)
于 2013-11-01T14:03:02.807 回答