我想从包含其他文件的路径+文件名的文件“filenames.dat”中读入
$ more filenames.dat
"/home/test1.dat"
"/home/test2.dat"
"/home/test3.dat"
然后检查这些文件是否存在。这是filenames.dat
中第一行的代码line=$(head -n 1 "filenames.dat")
[ -e "$line" ] && echo "files do exist" || echo "files do not exist"
然而,即使他们这样做,我也得到“文件不存在”。如果我做了
[ -e "/home/test1.dat" ] && echo "files do exist" || echo "files do not exist"
比文件存在!
答案 0 :(得分:2)
Literal 和语法引用是两回事:前者告诉shell如何解析你输入的代码,后者是你数据的一部分。
当你跑步时:
echo '"filenames.dat"' >filenames.dat
line=$(head -n 1 "filenames.dat")
... head
返回的行内的双引号是 literal :它们是数据的一部分。
相比之下,在[ -e "$line" ]
中,代码中的引号是 syntactic ;它们告诉shell将变量扩展的结果视为完全文字,没有字符串拆分或glob扩展。 (这是正确和可取的)。
运行[ -e "$line" ]
时,我们检查存在的是名为line
的变量的文字内容。因为这些文字内容包括head
返回的文字引号,所以我们查找包含文字引号的文件和目录名称。
因为您的实际文件名不包含文字引号,结果是找不到文件。
如果您希望保持数据格式不变,并使用数据中的字面引号,请遵循Bash: Reading quoted/escaped arguments correctly from a string
中的指导