这个问题在这里已有答案:
我有一个while循环应该迭代文本文件但停在第一行,我无法弄清楚原因。我的代码如下。
while read hadoop_accounts; do
if ! grep "no lock no remove"; then
echo "${hadoop_accounts%%:*}"
echo "${hadoop_accounts%%:*}" >> missing_no_lock_no_remove.txt
fi
done < hadoop_accounts.txt
当grep
在没有显式重定向或文件读取的情况下运行时,它会读取stdin。所有斯坦丁。你的while read
循环正在读取相同的标准输入。
因此,在grep
消耗掉你所有的stdin之后,下一个read
命令就没有任何东西可以消耗了。
简单的方法(性能更好)是对shell内部的子字符串检查,而不是每个处理的每行处理启动grep
的新副本:
while IFS= read -r hadoop_accounts; do
if ! [[ $hadoop_accounts = *"no lock no remove"* ]]; then
echo "${hadoop_accounts%%:*}"
echo "${hadoop_accounts%%:*}" >&3
fi
done < hadoop_accounts.txt 3>> missing_no_lock_no_remove.txt
另请注意,我们只打开输出文件一次,而不是每次我们想要写一行时重新打开它。
如果你真的想每次只用一行输入一遍又一遍地调用grep
,你可以这样做:
while IFS= read -r hadoop_accounts; do
if ! grep "no lock no remove" <<<"$hadoop_accounts"; then
echo "${hadoop_accounts%%:*}"
echo "${hadoop_accounts%%:*}" >&3
fi
done < hadoop_accounts.txt 3>> missing_no_lock_no_remove.txt
或者,甚至比上述任何一个更好,你可以在整个输入文件上一次运行grep
并在循环中读取它的输出:
while IFS= read -r hadoop_accounts; do
echo "${hadoop_accounts%%:*}"
echo "${hadoop_accounts%%:*}" >&3
done < <(grep -v 'no lock no remove' <hadoop_accounts.txt) 3>>missing_flags.txt