什么和&&将输出重定向到文件?

时间:2013-01-16 14:15:17

标签: bash unix redirect

我找到了一个bash script,它列出了文件开头或结尾带有空行的所有文件。

for f in `find . -type f`; do 
  for t in head tail; do 
    $t -1 $f  |egrep '^[  ]*$' >/dev/null && echo "blank line at the $t of $f" ;
  done; 
done

我想将输出传递给文件。我将echo行更改为:

$t -1 $f  |egrep '^[  ]*$' >/dev/null && echo "blank line at the $t of $f" > blank_lines.log

但是这没用。

我想问一下符号&&的作用以及为什么上述行不会将输出传递给文件。

4 个答案:

答案 0 :(得分:5)

这不会重定向输出,只有当第一个成功时才会添加另一个命令来执行。 I.e command1 && command2表示执行command1,如果成功则执行command2。当且仅当两个命令都成功时,执行此语句的结果才是成功。

答案 1 :(得分:3)

这是一个短路的'和'运营商。它不参与输出重定向。

在此上下文中,仅在左侧成功时才执行右侧。即如果egrep确实报告了一个空行,它只会打印出'...的空白行。

答案 2 :(得分:2)

正如其他人提到的那样&&是一个短路的运营商:

command1 && command2

执行command1,如果该命令没有错误运行(退出代码0),则执行command2。然后它返回command2的退出代码。

echo "foo" > /dev/null && echo "bar" > tmp.txt

确实有效,所以你的脚本不起作用的原因应该是别的。 也许尝试执行

$t -1 $f  |egrep '^[  ]*$' >/dev/null && echo "blank line at the $t of $f" > blank_lines.log

没有变量和for循环的行。

答案 3 :(得分:2)

重定向不起作用的原因是您使用>重定向输出。这个在将命令的输出写入它之前擦除文件,这意味着你只会看到写入它的最后一件事。要解决此问题,请使用>>进行追加(尽管您可能需要在开头截断文件以防止多次运行脚本累积的输出),或重定向整个循环的输出。

顺便说一下,如果任何文件名中包含空格或其他有趣的字符,那么用于迭代文件的for ... find构造将会非常失败。最好使用find ... -print0 | while IFS= read -d $'\0' ...(然后在$f周围使用双引号):

find . -type f -print0 | while IFS= read -d $'\0' f; do 
    for t in head tail; do 
        $t -1 "$f"  |egrep '^[  ]*$' >/dev/null && echo "blank line at the $t of $f"
    done
done > blank_lines.log
相关问题