我受到以下情况的困扰。
我有一个文件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中的行有空格。
我有两个build议的解决scheme,这两个都很臭:
1)我可以编辑list.txt,并用“THERE_SHOULD_BE_A_SPACE_HERE”全局replace所有的空格。 然后,我可以在我的循环内使用像sed这样的东西,用空格replaceTHERE_SHOULD_BE_A_SPACE_HERE,我将全部设置。 我不喜欢这个愚蠢的理由,如果list.txt中的任何一行包含THERE_SHOULD_BE_A_SPACE_HERE(这样恶意用户可以搞砸我),它将会失败。
2)我可以使用stdin的while循环,然后在每个循环中,我可以实际启动一个新的terminal,这将不会受到涉及到标准input的原始shell的影响。 我尝试过这样做,但确实得到它的工作,但它很丑陋:我想把所有这一切都包装在一个shell脚本中,我不希望这个shell脚本随机打开新窗口。 如果我能弄明白如何以某种方式在命令中调用一个新的shell并向它提供命令而不向stdin提供stdin,那么会怎么样呢?它的工作。 例如,这不起作用,我不知道为什么:
while read p; do bash -c "echo $p; echo ""Press enter for the next one.""; read x;"; done < list.txt
这个尝试似乎失败了,因为“read x”尽pipe处于不同的shell中,仍然看起来像是从list.txt中读取的。 但是我觉得我可能会接近这个 – 谁知道。
帮帮我!
您必须以不同的文件描述符打开
while read p <&3; do echo "$p" echo 'Hit enter for the next one' read x done 3< list.txt
更新:只是忽略下面的评论冗长的讨论。 这与问题或答案无关。
我可能会计数文件中的行,并使用例如每个迭代。 SED。 也可以通过改变条件来从标准输入中无限地读取: while true;
并用ctrl + c退出阅读。
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 -sx done
AWK也是这个的好工具。 通过输入迭代的简单方法是:
awk '{ print $0; printf "%s", "Hit enter for the next"; getline < "-" }' file
作为替代,你可以从stderr中读取,默认情况下也连接到tty。 下面还包括对这个假设的测试:
( tty -s <& 2|| exit 1 while read -r line; do echo "$line" echo 'Hit enter' read x <& 2 done < file )