所以,我已经知道如何检查特定文件是否存在:
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
答案中的测试,因为您在问题中反复使用“存在”一词,而没有提及有关文件类型的任何内容。