【问题标题】:sh: Test for existence of filessh:测试文件是否存在
【发布时间】:2012-01-19 05:26:28
【问题描述】:

如何使用bash 测试目录中是否存在文件?

if ... ; then
   echo 'Found some!'
fi

明确地说,我不想测试 特定 文件是否存在。我想测试一个特定目录是否包含 any 个文件。


我去了:

(
   shopt -s dotglob nullglob
   existing_files=( ./* )
   if [[ ${#existing_files[@]} -gt 0 ]] ; then
      some_command "${existing_files[@]}"
   fi
)

使用数组避免了两次读取文件列表的竞争条件。

【问题讨论】:

  • 目录包含子目录但没有普通文件怎么办?
  • @Keith Thompson,不会发生。
  • 如果目录比较大,做一个 glob 是个坏主意。 ls -f 会快得多。
  • @William Pursell,如何从ls 加载数组?

标签: bash sh


【解决方案1】:

来自手册页:

   -f file
          True if file exists and is a regular file.

所以:

if [ -f someFileName ]; then echo 'Found some!'; fi

编辑:我看到您已经得到了答案,但为了完整起见,您可以使用 Checking from shell script if a directory contains files 中的信息 - 如果您想忽略隐藏文件,请丢失 dotglob 选项。

【讨论】:

  • 测试特定文件是否存在。我想测试任何文件是否存在。
  • 啊,我误会了。好的,您需要捕获隐藏(即 .xyz)文件吗?
  • 不,忽略隐藏文件没问题。
【解决方案2】:

我通常只使用便宜的 ls -A 来查看是否有响应。

伪可能正确的语法示例-ahoy:

if [[ $(ls -A my_directory_path_variable ) ]] then....

编辑,这将起作用:

myDir=(./*) if [ ${#myDir[@]} -gt 1 ]; then echo "there's something down here"; fi

【讨论】:

  • 这个答案应该对你有用,即使它有点骇人听闻。我将尝试一个全 sh/bash 解决方案。
  • 感觉有点扭曲,但确实有效。我期待看到你想出什么:)
  • myDir=(./*) if [ ${#myDir[@]} -gt 1 ];然后回显“这里有东西”; fi ...给你。即插即用。
  • @tristan:如果目录仅包含名称以. 开头的文件,则会失败。
  • 我的第二个版本 ever 在 OSX 上对包含 300 多个文件的目录进行测试时稍微快一点 - 我看到大约 0.001 秒的差异。不知道这是否重要,但是嘿。
【解决方案3】:

您可以在if 语句中使用ls,因此:

if [[ "$(ls -a1 | egrep -v '^\.$|^\.\.$')" = "" ]] ; then echo empty ; fi

或者,感谢 ikegami,

if [[ "$(ls -A)" = "" ]] ; then echo empty ; fi

或者,甚至更短:

if [[ -z "$(ls -A)" ]] ; then echo empty ; fi

这些基本上列出了当前目录中所有既不是.也不是..的文件(包括隐藏文件)。

如果该列表为空,则目录为空。

如果你想打折隐藏文件,可以简化为:

if [[ "$(ls)" = "" ]] ; then echo empty ; fi

bash 的解决方案(不调用lsegrep 等外部程序)可以按如下方式完成:

emp=Y; for i in *; do if [[ $i != "*" ]]; then emp=N; break; fi; done; echo $emp

这不是世界上最漂亮的代码,它只是将emp 设置为Y,然后对于每个真实文件,将其设置为N 并从for 中断循环效率。如果文件为零,则保持为Y

【讨论】:

  • 如果您s/ls -a/ls -A/,则不再需要egrep
  • 既然可以留在 bash 中,为什么还要使用 egrep?此外,无需将结果与空字符串进行比较。这比它需要的要贵。
  • @tristan,这可能就是为什么你得到了接受而不是我 :-) 但是,你应该记住,我上面的解决方案,而不是你的,都不是“在 bash 中”。它们都调用ls 和外部可执行文件。我将添加一个仅限 bash 的解决方案,尽管它会很丑。
  • @paxdiablo,我重新阅读了我的评论并意识到我对“磨料”很重视,而对“你知道我不知道的事情吗?”很轻。哎呀。对不起。
  • 这种在纯 bash 中做事的想法是愚蠢的。在我的盒子上,在一个中等大小的目录(9640 个文件)中,ls -f |头| grep 的运行速度比在 shell 中运行 glob 快大约 32 倍。使用外部工具没有任何问题。
【解决方案4】:

试试这个

if [ -f /tmp/foo.txt ]
then
    echo the file exists
fi

参考:http://tldp.org/LDP/abs/html/fto.html

您可能还想看看这个:http://tldp.org/LDP/abs/html/fto.html

请问目录是否为空

$ find "/tmp" -type f -exec echo Found file {} \;

【讨论】:

  • 测试特定文件是否存在。我想测试任何文件是否存在。
【解决方案5】:
#!/bin/bash

if [ -e $1 ]; then
        echo "File exists"
else 
       echo "Files does not exist"
fi 

【讨论】:

  • 测试特定文件是否存在。我想测试特定目录中是否存在任何文件。
【解决方案6】:

我没有一个好的纯 sh/bash 解决方案,但是在 Perl 中很容易做到:

#!/usr/bin/perl

use strict;
use warnings;

die "Usage: $0 dir\n" if scalar @ARGV != 1 or not -d $ARGV[0];
opendir my $DIR, $ARGV[0] or die "$ARGV[0]: $!\n";
my @files = readdir $DIR;
closedir $DIR;
if (scalar @files == 2) { # . and ..
    exit 0;
}
else {
    exit 1;
}

将其命名为 emptydir 并将其放在 $PATH 的某个位置,然后:

if emptydir dir ; then
    echo "dir is empty"
else
    echo "dir is not empty"
fi

如果你不给它参数,两个或更多参数,或者一个不是目录的参数,它会以错误消息而死;如果您喜欢不同的行为,很容易改变。

【讨论】:

    【解决方案7】:
    # tested on Linux BASH
    
    directory=$1
    
    if test $(stat -c %h $directory) -gt 2;
    then
       echo "not empty"
    else
       echo "empty"
    fi
    

    【讨论】:

      【解决方案8】:

      为了好玩:

      if ( shopt -s nullglob ; perl -e'exit !@ARGV' ./* ) ; then
         echo 'Found some!'
      fi
      

      (不检查隐藏文件)

      【讨论】:

        猜你喜欢
        • 2011-02-16
        • 1970-01-01
        • 1970-01-01
        • 2011-05-27
        • 2020-06-18
        • 2010-12-28
        • 1970-01-01
        • 1970-01-01
        • 2017-07-29
        相关资源
        最近更新 更多