Bash - 检查两个文件是否存在并打印现有文件各自的文件名

Bash - 检查两个文件是否存在并打印现有文件各自的文件名

所以,我已经知道如何检查特定文件是否存在:

if [ -f ~/file1 ]; then echo "is there" ; else echo "not there" ; fi
if [ -f ~/file2 ]; then echo "is there" ; else echo "not there" ; fi

并且对于两个文件的存在:

[[ -f file1 && -f file2 ]] && echo "both" || echo "not"

然而,我不知道的是如何知道两个不同文件的存在,同时还打印它们各自的名称(如果它们中的任何一个存在,如果两者都存在,或者如果它们都不存在则打印错误......)

以便:

  • 如果 file1 存在但 file2 不存在 -> 它将打印 file1 为现有文件,反之亦然。

  • 如果 file1 和 file2 存在 -> 打印它们的文件名。

  • 如果不存在 -> 它们的文件名将被打印为不存在。

答案1

我会循环执行此操作:

for pathname in ~/file1 ~/file2; do
    if [ -e "$pathname" ]; then
        printf '"%s" exists\n' "$pathname"
    else
        printf '"%s" does not exist\n' "$pathname"
    fi
done

这基本上对循环头中提到的每个路径名的存在进行单一测试,并根据测试结果决定输出内容。输出提到了检查的路径名和测试结果。

如果路径名与简单模式匹配,则可以在循环中使用:

for pathname in ~/file[12]; do ...; done

这个问题也可以解释为:打印每个现有的路径名,但如果没有任何文件存在,则打印所有路径名和一条说明它们不存在的注释。

set -- ~/file1 ~/file2

found=false
for pathname do
    if [ -e "$pathname" ]; then
        printf '"%s" exists\n' "$pathname"
        found=true
    fi
done

if ! "$found"; then
    printf '"%s" does not exist\n' "$@"
fi

我在这里使用位置参数列表作为列表,保存我们想要检查的路径名。我这样做是因为我们可能想循环这个列表两次;一次是在我们的-e测试中,然后再次(隐式地)在调用中printf如果没有发现文件存在。

使用数组bash代替(需要更多的输入):

files=( ~/file1 ~/file2 )

found=false
for pathname in "${files[@]}"; do
    if [ -e "$pathname" ]; then
        printf '"%s" exists\n' "$pathname"
        found=true
    fi
done

if ! "$found"; then
    printf '"%s" does not exist\n' "${files[@]}"
fi

注意files=( ~/file1 ~/file2 )也可以写成

files[0]=~/file1
files[1]=~/file2

-f只是关于测试与测试的评论-e。测试-e检验存在,而-f测试检验存在文件类型。如果路径名不引用常规文件(或到常规文件的符号链接),则测试-f可能为假,而-e同时测试可能为真。 “常规文件”是指不是目录、套接字、命名管道或任何其他常见 Unix 文件类型的文件。

我选择了-e测试而不是-f答案中的测试,因为您在问题中反复使用“存在”一词,而没有提及有关文件类型的任何内容。

相关内容