use*_*772 7 shell scripting bash files
运行时参数如下: $1 是包含文件列表的文件的路径 $2 是包含文件的目录的路径 我想要做的是检查 $1 中列出的每个文件是否存在于 $2 目录中
我在想这样的事情:
for f in 'cat $1'
do
if (FILEEXISTSIN$2DIRECTORY)
then echo '$f exists in $2'
else echo '$f is missing in $2' sleep 5 exit
fi
done
Run Code Online (Sandbox Code Playgroud)
如您所见,我希望这样,如果目录中$1
不存在 中列出的任何文件$2
,则脚本会声明该文件然后关闭。我唯一无法理解的(FILEEXISTSIN$2DIRECTORY)
部分是部分。我知道你可以做到,[ -e $f ]
但我不知道你如何确保它检查它是否存在于$2
目录中。
Sté*_*las 12
在外壳的方式,你会写:
comm -23 <(sort -u < "$1") <(ls -A -- "${2%/}/")
Run Code Online (Sandbox Code Playgroud)
(假设 shell 支持进程替换,如 ksh、zsh 或 bash)
comm
是报告两个排序文件之间的公共行的命令。它显示在 3 个选项卡分隔的列中:
并且您可以通过-1
、-2
和-3
选项来删除相应的列。
所以上面,它只会报告第一列:文件列表中的行,但不在输出中的行ls
(ls
默认情况下对文件列表进行排序,我们假设其中的文件名不包含换行符)。
在 中zsh
,您将使用其${A:|B}
数组减法运算符:
#! /bin/zsh -
files_in_list=(${(f)"$(<$1)"})
files_in_dir=(${2%/}/*(ND:t))
print -rC1 -- ${files_in_list:|files_in_dir}
Run Code Online (Sandbox Code Playgroud)
迭代文件中的行的最佳方法是read
在 while 循环中使用内置函数。这就是你要找的:
while IFS= read -r f; do
if [[ -e $2/$f ]]; then
printf '%s exists in %s\n' "$f" "$2"
else
printf '%s is missing in %s\n' "$f" "$2"
exit 1
fi
done < "$1"
Run Code Online (Sandbox Code Playgroud)