bash 使用通配符计算路径中的文件并分配给变量

bash 使用通配符计算路径中的文件并分配给变量

我缺少什么?

我想找出目录中有多少文件与给定模式匹配并将其分配给变量。

如果我直接在命令行上输入它,它就可以正常工作

ls /backups/system\ db\ files/temp/daily/backup_filename_202203*.tar.gz | wc -l

(注意,是*创建备份的日期,例如01、等)0203

但一旦我将它添加到我的 bash 脚本中,它就会失败。

到目前为止我有:

base_dir="/backups/system\ db\ files/temp" 
sub_dir="${base_dir}/daily"
filename_base="backup_filename_"

然后我尝试运行:

counter=$(ls ${sub_dir}/${filename_base_}202203*.tar.gz | wc -l)

或带引号:

counter=$(ls "${sub_dir}/${filename_base_}202203*.tar.gz" | wc -l)

第一个失败,因为它尝试根据空格分割它。第二个不扩展 来*查找通配符。

我尝试过引用其中的一些内容,例如

counter=$(ls "${sub_dir}/${filename_base_}"202203*.tar.gz | wc -l)

但它再次忽略了通配符。

我一直在寻找,但我一生都找不到一种方法来获取匹配文件的总数。

答案1

您的问题是您的目录没有被调用/backups/system\ db\ files/temp,而是被调用了backups/system db files/temp。当引用字符串时,反斜杠成为字符串的一部分。由于您引用了该字符串,因此无需转义空格。您filename_base在一些地方的变量拼写也错误(带有尾随下划线)。

您也不需要使用lswc来计算与 shell 模式匹配的名称数量。请记住,文件名中可以​​包含换行符,并且wc -l计算的是换行符,而不是文件名。

要查看 shell 模式有多少个匹配项,您所需要做的就是将模式扩展为数组或位置参数列表,然后查看该数组或列表的长度。

使用具有示例模式的数组:

list=( "some/path to the/files"/*.txt )

count=${#list[@]}

使用位置参数列表:

set -- "some/path to the/files"/*.txt

count=$#

bashshell 中,您必须设置nullglobshell 选项来shopt -s nullglob正确处理空目录(如果该模式不匹配任何内容,则该模式通常不会展开)。

如果没有设置nullglob,您可以使用以下命令来测试是否没有匹配项

list=( "some/path to the/files"/*.txt )
count=${#list[@]}

if [ ! -e "${list[0]}" ] && [ ! -h "${list[0]}" ]; then
    count=0
fi

或者,如果您使用位置参数,

set -- "some/path to the/files"/*.txt
count=$#

if [ ! -e "$1" ] && [ ! -h "$1" ]; then
    count=0
fi

如果否定-e-h测试是真的对于结果列表中的第一个元素,则第一个元素不是现有文件,也不是损坏的符号链接。这意味着该模式没有匹配项。

答案2

当你已经引用它们时,不要转义空格,否则反斜杠将按字面意思理解:

base_dir="/backups/system\ db\ files/temp" 

应该

base_dir="/backups/system db files/temp"

还有为什么你_${filename_base_}

你的最后一个命令应该有大概如果其他一切都正确,则有效:

counter=$(ls "${sub_dir}/${filename_base}"202203*.tar.gz | wc -l)

无论如何,你不应该解析ls

而是使用find

find "${sub_dir}" -name "${filename_base}202203*.tar.gz" -printf '.' | wc -c

或一个数组:

shopt -s nullglob
files=("${sub_dir}/${filename_base}"202203*.tar.gz)
echo "${#files[@]}"

您需要该nullglob选项,否则结果将是1没有文件与您的模式匹配,因为字符串将按字面意思处理。

相关内容