Linux 在bash中循环文件中的行,而不使用stdin

Linux 在bash中循环文件中的行,而不使用stdin,linux,bash,shell,loops,Linux,Bash,Shell,Loops,我被下列情况弄糊涂了 我有一个文件list.txt,我想在bash中以循环方式逐行运行它。list.txt中的典型行中有空格。问题是循环包含一个“read”命令。我想用bash编写这个循环,而不是像perl这样的东西。我做不到:-( 下面是我通常如何编写循环以逐行读取文件: while read p; do echo $p echo "Hit enter for the next one." read x done < list.txt 因为list.txt中的行在中有空格

我被下列情况弄糊涂了

我有一个文件list.txt,我想在bash中以循环方式逐行运行它。list.txt中的典型行中有空格。问题是循环包含一个“read”命令。我想用bash编写这个循环,而不是像perl这样的东西。我做不到:-(

下面是我通常如何编写循环以逐行读取文件:

while read p; do
  echo $p
  echo "Hit enter for the next one."
  read x
done < list.txt
因为list.txt中的行在中有空格

我提出了两个解决方案,都很糟糕:

1) 我可以编辑list.txt,并用“THERE\u SHOULD\u A\u SPACE\u HERE”全局替换所有空格。然后,我可以在我的循环中使用sed之类的东西,用一个空格来替换这里应该是一个空格,这样我就万事大吉了。我不喜欢这个,因为愚蠢的原因是,如果list.txt中的任何一行包含短语THERE\u SHOULD\u BE\u A\u SPACE\u,它就会失败(所以恶意用户会把我搞砸)

2) 我可以将while循环与stdin一起使用,然后在每个循环中,我可以实际启动一个新的终端,这不会受到原始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
读取p时
;做
bash-c“echo$p;echo”“按enter键进入下一个。”“读取x;”;
完成
这一尝试似乎失败了,因为“read x”尽管在不同的shell中,但似乎仍在读取list.txt。但我觉得我可能和这个很接近——谁知道呢


救命啊

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

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

在读取p时,您也可以从stderr读取,默认情况下,stderr也连接到tty。然后,以下内容还包括对该假设的测试:

(
tty -s <& 2|| exit 1
while read -r line; do
    echo "$line"
    echo 'Hit enter'
    read x <& 2
done < file
)
(

tty-s我可能会计算文件中的行数,并使用例如sed对每一行进行迭代。通过将while条件更改为:
while true;
并使用ctrl+c退出读取,也可以从stdin无限读取

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

awk '{ print  $0; printf "%s", "Hit enter for the next"; getline < "-" }' file
awk'{print$0;printf“%s”,点击回车键进入下一个“getline<“-”}文件

另外,使用
IFS=''read-r p@chepner:好的,添加了
-r
IFS
我有时会在脚本的顶部取消设置。毕竟,我们在这里谈论的是shell。它永远不会是超级安全的。我们必须依赖于半正常的环境。@JoSo,如果你说
IFS=read x
你只是在一段时间内更改IFS读取命令的名称。()@格伦·杰克曼:我知道。但是我已经放弃了100%按照规范创建shell脚本,而是现在编写更可读的脚本。你有没有尝试过将零字节读入shell变量?或者用包含尾随换行符的输出进行命令替换?你也可以将
read
写成
read-u3
而不是
read No需要对一个问题给出错误/复杂的答案,并给出一个可接受的、清晰和简单的答案。。。
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 '{ print  $0; printf "%s", "Hit enter for the next"; getline < "-" }' file