while循环只在bash中的第一行文件上运行[重复]

问题描述 投票:1回答:1

我有一个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
bash
1个回答
3
投票

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
© www.soinside.com 2019 - 2024. All rights reserved.