我有包含文件名的示例 CSV 文件
f1
f2
f3
我想在目录中搜索这些文件名,下面是我的代码
while read f1
do
ls -t | grep "$f1"
if[ $? = 0 ]
then
echo file exists
else
echo file does not exists
fi
done<sample.csv
不知何故,$f1
变量值并没有取代获取空白值。
答案1
该ls
命令是列出目录的内容,而不是测试文件是否存在。通常也不grep
适合处理文件名,因为文件名在技术上可以包含换行符(并且grep
是一种面向行的工具,就像大多数处理文本文件的实用程序一样)。
您在测试中还存在语法错误if
(前面缺少空格[
)。
根据评论,输入文件也是DOS文本文件。这意味着从文件中读取的每一行末尾都会有一个额外的回车符,这又意味着当 Unix 脚本(或其他 Unix 工具)读取文件时,回车符将成为数据的一部分读。对于这个特定的脚本,这反过来意味着从文件中读取的文件名不太可能与文件系统中的现有文件名相匹配(回车符实际上在 Unix 文件名中有效,但很少或从未见过其他文件名)而非错误)。
可以使用转换实用程序将 DOS 文本文件转换为 Unix 文本文件格式dos2unix
。
要测试文件是否存在,只需使用-e
以下测试[ ... ]
:
while IFS= read -r name; do
if [ -e "$name" ]; then
printf '%s exists\n' "$name"
else
printf '%s does not exist\n' "$name"
fi
done <sample.csv
这假设文件sample.csv
file 每行包含一个文件名或路径名。
答案2
您的代码中缺少分号/换行符,导致它根本无法工作。 if 后面还少了一个空格。解决这个问题我们得到了一个衬里:
while read f1; do ls -t | grep "$f1"; if [ $? = 0 ]; then echo file exists; else echo file does not exists; fi; done
我们还可以在有分号的地方使用换行符,这可能更容易阅读。 (但我将代码保持在靠近您的位置)。现在可以正常工作了。例如,我们可以将其保存到test.sh
,然后它就会按预期工作。例如
$ echo test.sh | bash test.sh
test.sh
file exists
答案3
您可以编写zsh
如下脚本:
#! /bin/zsh -
# list of files to find on stdin or in file arguments, LF delimited
to_find=(${(f)"$(cat -- "$@")"})
in_current_dir=(*(ND))
# print files in both lists, LF delimited:
print -rC1 -- ${in_current_dir:*to_find}