如果名称不在文本文件中,如何从目录中删除文件? Bash 脚本

How to remove files from a directory if their names are not in a text file? Bash script

我正在编写一个 bash 脚本,希望它告诉我目录中的文件名是否出现在文本文件中,如果没有,则将其删除。

像这样:

counter = 1
numFiles = ls -1 TestDir/ | wc -l 
while [$counter -lt $numFiles]
do
     if [file in TestDir/ not in fileNames.txt]
     then
          rm file
     fi
     ((counter++))
done

所以我需要帮助的是 if 语句,它仍然是伪代码。

您可以大大简化您的脚本逻辑:

#/bin/bash

# for loop to iterate over all files in the testdir
for file in TestDir/*
do
    # if grep exit code is 1 (file not found in the text document), we delete the file
    [[ ! $(grep -x "$file" fileNames.txt &> /dev/null) ]] && rm "$file"
done

看起来你有一个可行的解决方案,但我想我也会提供这个,因为它可能仍然对你或其他人有帮助。

find /Path/To/TestDir -type f ! -name '.*' -exec basename {} + | grep -xvF -f /Path/To/filenames.txt"

细分

find: 这会获取指定目录(即 TestDir)中符合给定条件的文件路径。在本例中,我指定 return 仅常规文件 (-type f) 其名称不以句点开头 (-name '.*')。然后它使用自己的内置实用程序执行下一个命令:

basename: 给定一个文件路径(这是 find 吐出来的),它只会 return 基本文件名,或者,更具体地说,最后一个 /.

之后的所有内容

|: 这是一个命令管道,它将上一个命令的输出用作下一个命令的输入。

grep: 这是一个 regular-expression 匹配实用程序,在本例中,它有两个文件列表:一个通过管道输入来自 find——你的 TestDir 目录的文件;以及 filenames.txt 中列出的文件。通常,文本文件中的文件名将用于匹配由 find 编辑的文件名 return,匹配的文件名将作为输出给出。但是,-v 标志反转了匹配过程,因此 grep return 那些 不 [=60] 的文件名=]匹配。

结果是存在于目录 TestDir 中的文件列表,但 没有 出现在 filenames.txt 文件中。这些是您要删除的文件,因此您只需在参数扩展 $(...) 中使用这行代码即可提供 rm 与它能够删除的文件。

完整的命令链——在你 cd 进入 TestDir 之后——看起来像这样:

rm $(find . -type f ! -name '.*' -exec basename {} + | grep -xvF -f filenames.txt")