Bash:检查目录是否只包含带有特定后缀的文件
我正在尝试编写一个脚本来检查目录是否只包含 特定类型的文件(和/或文件夹),将返回1表示false,0表示true IE:我想检查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"
/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