文本文件包含 sha5 哈希值和文件的列表。这些应该被删除。如下所示:
01115896a225d60b6e8b833b10955d2c "./path/to file/file-name"
01115896a225d60b6e8b833b10955d2c "./path/to file/file name"
01159159b1bfaaa35d0055abf185f662 "./path/to file/filename"
我提取文件名,并将 sh5 哈希与以下内容匹配:
b=$(grep $sha5key data-file.txt | awk {'first = $1; $1=""; print $0'}|sed 's/^ //g')
我现在验证该文件存在:
我的 $b 结果如下所示:"./path/to file/filename"
文件/路径位于“”内
if test -f "$b"; then
echo $b
rm -f $b
fi
这些文件确实存在(可以手动删除,这种方法可行),但是无法在脚本中删除。缺少什么或出了什么问题?
答案1
作为一般规则,shell 不会将数据(从文件、变量等中读取的数据)中的引号视为 shell 语法的一部分,而是将其视为数据的一部分。简而言之,引号大约数据,不是在数据。这意味着要获取文件名,您必须在解析和处理文件的过程中删除双引号。
如果格式足够一致(即每行由一个井号、一个空格、一个双引号、文件名和另一个双引号组成),则可以使用以下命令提取文件名sed
:
b=$(sed -nE "s/^${$sha5key} \"(.*)\"/\\1/p" data-file.txt)
工作原理:该-n
选项指示sed
不要打印文件中的行,除非明确指示(p
替换选项将执行此操作)。该-E
选项告诉它使用扩展的正则表达式语法,这更简洁一些。然后有一个s
(替换)命令,它将预期的模式与正确的哈希值匹配,括号选择双引号之间的任何内容;替换模式\1
(使用双斜杠将其转义)将整行替换为括号中的内容,即文件名。该p
选项告诉它打印结果;因为这种情况会发生仅有的如果发生替换,则此选项和-n
选项意味着只打印匹配的行。
然后你需要在变量引用周围加上双引号。如果没有它们,shell 会拆分文件名,并且(例如)尝试删除“./path/to”和“file/file-name”,而不是“./path/to file/file-name”。它还可能会被文件名中的其他一些字符所混淆。你应该几乎总是用双引号括住变量引用。
if test -f "$b"; then
echo "$b"
rm -f "$b"
fi
请注意,如果多行有匹配的哈希值,您将得到一个结果,其中包含多个文件名,这些文件名由换行符分隔。如果这是可能的,您需要从中解析出单独的文件名。
答案2
如果有多个匹配的文件,b
则 是包含所有文件的单个字符串。因此,存在性测试就是查找名为 的文件"./path/to file/file-name1"\n"/path/to file/file name2"\n
。
您可能希望将所有内容放入数组中并迭代数组成员。