Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash:检查目录是否只包含带有特定后缀的文件_Bash_Directory_File Exists - Fatal编程技术网

Bash:检查目录是否只包含带有特定后缀的文件

Bash:检查目录是否只包含带有特定后缀的文件,bash,directory,file-exists,Bash,Directory,File Exists,我正在尝试编写一个脚本来检查目录是否只包含 特定类型的文件(和/或文件夹),将返回1表示false,0表示true IE:我想检查/my/dir/是否只包含*.gz文件而不包含其他文件 到目前为止,我已经做到了这一点,但它似乎没有达到预期的效果: # Basic vars readonly THIS_JOB=${0##*/} readonly ARGS_NBR=1 declare dir_in=$1 dir_in=$1"/*.gz"

我正在尝试编写一个脚本来检查目录是否只包含 特定类型的文件(和/或文件夹),将返回1表示false,0表示true

IE:我想检查
/my/dir/
是否只包含
*.gz
文件而不包含其他文件

到目前为止,我已经做到了这一点,但它似乎没有达到预期的效果:

# Basic vars
readonly       THIS_JOB=${0##*/}
readonly       ARGS_NBR=1


declare        dir_in=$1


dir_in=$1"/*.gz"
#echo $dir_in

files=$(shopt -s nullglob dotglob; echo ! $dir_in)
echo $files

if (( ${#files} ))
then
    echo "Success: Directory contains files."
    exit 0
else
    echo "Failure: Directory is empty (or does not exist or is a file)"
    exit 1
fi
我想检查/my/dir/是否只包含*.gz文件而不包含其他文件

使用
find
而不是球形化。使用
find
和解析find输出非常容易。对于简单的脚本来说,Globulation很简单,但是一旦您想要解析“目录中的所有文件”并进行一些过滤之类的操作,那么使用
查找
就更容易(更安全):

find "$1" -mindepth 1 -maxdepth 1 \! -name '*.gz' -o \! -type f | wc -l | xargs test 0 -eq
这将查找目录中未命名为
*.gz
或不是文件的所有“事物”(因此
mkdir a.gz
已被计算),对它们进行计数,然后测试它们的计数是否等于0。如果计数等于0,
xargs test 0-eq
将返回0,否则,它将返回介于
1-125之间的状态。如果愿意,可以使用简单的
| | return 1
处理非零返回状态

您可以通过一个简单的bash替换来删除
xargs
,并使用中的方法来获得
test
返回值,即
0
1

[ 0 -eq "$(find "$1" -mindepth 1 -maxdepth 1 \! -name '*.gz' -o \! -type f -print '.' | wc -c)" ]
请记住,脚本的退出状态是最后执行的命令的退出状态。因此,如果您愿意,您不需要脚本中的任何其他内容,只有一个shebang和这一行就足够了

我想检查/my/dir/是否只包含*.gz文件而不包含其他文件

使用
find
而不是球形化。使用
find
和解析find输出非常容易。对于简单的脚本来说,Globulation很简单,但是一旦您想要解析“目录中的所有文件”并进行一些过滤之类的操作,那么使用
查找
就更容易(更安全):

find "$1" -mindepth 1 -maxdepth 1 \! -name '*.gz' -o \! -type f | wc -l | xargs test 0 -eq
这将查找目录中未命名为
*.gz
或不是文件的所有“事物”(因此
mkdir a.gz
已被计算),对它们进行计数,然后测试它们的计数是否等于0。如果计数等于0,
xargs test 0-eq
将返回0,否则,它将返回介于
1-125之间的状态。如果愿意,可以使用简单的
| | return 1
处理非零返回状态

您可以通过一个简单的bash替换来删除
xargs
,并使用中的方法来获得
test
返回值,即
0
1

[ 0 -eq "$(find "$1" -mindepth 1 -maxdepth 1 \! -name '*.gz' -o \! -type f -print '.' | wc -c)" ]

请记住,脚本的退出状态是最后执行的命令的退出状态。因此,如果愿意,您不需要脚本中的任何其他内容,只有一个shebang和这一行就足够了。

因为您使用的是bash,所以可以使用另一个设置:
GLOBIGNORE

#!/bin/bash

containsonly(){
    dir="$1"
    glob="$2"

    if [ ! -d "$dir" ]; then
        echo 1>&2 "Failure: directory does not exist"
        return 2
    fi

    local res=$(
        cd "$dir"
        GLOBIGNORE=$glob"
        shopt -s nullglob dotglob
        echo *
    )
    if [ ${#res} = 0 ]; then
        echo 1>&2 "Success: directory contains no extra files"
        return 0
    else
        echo 1>&2 "Failure: directory contains extra files"
        return 1
    fi
}

# ...

containsonly myfolder '*.gz'


因为您使用的是bash,所以可以使用另一个设置:
GLOBIGNORE

#!/bin/bash

containsonly(){
    dir="$1"
    glob="$2"

    if [ ! -d "$dir" ]; then
        echo 1>&2 "Failure: directory does not exist"
        return 2
    fi

    local res=$(
        cd "$dir"
        GLOBIGNORE=$glob"
        shopt -s nullglob dotglob
        echo *
    )
    if [ ${#res} = 0 ]; then
        echo 1>&2 "Success: directory contains no extra files"
        return 0
    else
        echo 1>&2 "Failure: directory contains extra files"
        return 1
    fi
}

# ...

containsonly myfolder '*.gz'


使用Bash的
extglob
!(*.gz)
grep

$ if grep -qs . path/!(*.gz) ; then echo yes ; else echo nope ; fi
-q, --quiet, --silent
       Quiet;  do  not  write  anything  to  standard   output.    Exit
       immediately  with  zero status if any match is found, even if an
       error was detected.  Also see the -s or --no-messages option.

-s, --no-messages
       Suppress error messages about nonexistent or unreadable files.
man grep

$ if grep -qs . path/!(*.gz) ; then echo yes ; else echo nope ; fi
-q, --quiet, --silent
       Quiet;  do  not  write  anything  to  standard   output.    Exit
       immediately  with  zero status if any match is found, even if an
       error was detected.  Also see the -s or --no-messages option.

-s, --no-messages
       Suppress error messages about nonexistent or unreadable files.

使用Bash的
extglob
!(*.gz)
grep

$ if grep -qs . path/!(*.gz) ; then echo yes ; else echo nope ; fi
-q, --quiet, --silent
       Quiet;  do  not  write  anything  to  standard   output.    Exit
       immediately  with  zero status if any match is found, even if an
       error was detected.  Also see the -s or --no-messages option.

-s, --no-messages
       Suppress error messages about nonexistent or unreadable files.
man grep

$ if grep -qs . path/!(*.gz) ; then echo yes ; else echo nope ; fi
-q, --quiet, --silent
       Quiet;  do  not  write  anything  to  standard   output.    Exit
       immediately  with  zero status if any match is found, even if an
       error was detected.  Also see the -s or --no-messages option.

-s, --no-messages
       Suppress error messages about nonexistent or unreadable files.

一些人建议对所有与全局模式不匹配的文件进行计数
*.gz
。根据文件的数量,这可能效率很低。对于您的工作,只找到一个文件就足够了,它与您的全局搜索模式不匹配。使用
find
-quite
操作在第一次匹配后退出:

if [ -z "$(find /usr/share/man/man1/* -not -name '*.gz' -print -quit)" ]
then echo only gz
fi

一些人建议对所有与全局模式不匹配的文件进行计数
*.gz
。根据文件的数量,这可能效率很低。对于您的工作,只找到一个文件就足够了,它与您的全局搜索模式不匹配。使用
find
-quite
操作在第一次匹配后退出:

if [ -z "$(find /usr/share/man/man1/* -not -name '*.gz' -print -quit)" ]
then echo only gz
fi

不确定能否保证xargs将返回123(freebsd返回1),但肯定应该是介于1到125之间的值不确定能否保证xargs将返回123(freebsd返回1),但肯定应该是介于1到125之间的值
-not
-quit
我认为不符合POSIX<代码>-不
可以简单地用
替换但是
-quit
busybox
中不存在。在这种情况下,既然我们有了bash,我想可以用类似于
-execbash-c'kill-PIPE$PPID'的东西来替换它
(或者只是
find…|head-n1
)@jhnc使用一个GNU工具Bash的人,可能也使用其他GNU工具,并且不关心POSIX兼容性。我在freebsd上使用Bash,但许多实用程序不是GNU
-不是
,而且
-quit
不是POSIX兼容的,我认为<代码>-不
可以简单地用
替换但是
-quit
busybox
中不存在。在这种情况下,既然我们有了bash,我想可以用类似于
-execbash-c'kill-PIPE$PPID'的东西来替换它
(或者只是
find…| head-n1
)@jhnc使用一个GNU工具Bash的人,可能也使用其他GNU工具,并且不关心POSIX合规性。我在freebsd上使用Bash,但许多实用程序不是GNU