循环遍历bash中的文件中的行,而不使用stdin

Yan*_*ick 8 linux bash shell loops

我被以下情况所困扰.

我有一个文件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
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为当然"read x"将从list.txt而不是键盘读取.

这也不起作用:

for i in `cat list.txt`; do
    echo $i
    echo "Hit enter for the next one."
  read x
done
Run Code Online (Sandbox Code Playgroud)

因为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)我可以使用带有stdin的while循环,然后在每个循环中我实际上可以启动例如一个新的终端,它不会受到原始shell中涉及stdin的事件的影响.我尝试了这个,我确实让它工作,但它很丑:我想把所有这些包装在一个shell脚本中,我不希望那个shell脚本随机打开新窗口.如果我能弄清楚如何以某种方式调用命令中的新shell并将命令提供给它而不向其提供stdin,那么什么会很好,以及可能以某种方式解决这个问题的答案,但我无法得到它工作.例如,这不起作用,我不知道为什么:

while read p; do 
  bash -c "echo $p; echo ""Press enter for the next one.""; read x;"; 
done < list.txt
Run Code Online (Sandbox Code Playgroud)

这种尝试似乎失败了,因为"读取x",尽管在某种程度上处于不同的shell中,仍然看似从list.txt中读取.但我觉得我可能会接近这个 - 谁知道呢.

救命!

Jo *_* So 15

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

while read p <&3; do
    echo "$p"
    echo 'Hit enter for the next one'
    read x
done 3< list.txt
Run Code Online (Sandbox Code Playgroud)

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

  • 另外,使用`IFS =''read -rp <&3`以确保从文件中获取确切的行,而不会丢失前导或尾随空格或将任何反斜杠作为转义字符处理. (5认同)
  • 您也可以将`read`写成`read -u 3`而不是`read <&3`(问题被标记为bash). (3认同)
  • @JoSo,如果你说'IFS = read x`,你只需要在读命令的持续时间内改变IFS*.([参考](http://www.gnu.org/software/bash/manual/bashref.html#Simple-Command-Expansion)) (2认同)