【问题标题】:Delete files and folders in a directory which don't match a text list删除目录中与文本列表不匹配的文件和文件夹
【发布时间】:2020-05-17 21:48:52
【问题描述】:

假设我有一个名为dir 的目录。在那个目录中,我有这些文件夹和文件:

folder1
folder2
folder3
file1.mp4
file2.mkv
file3.mp4

我有一个名为 list.txt 的文本文件,其中包含以下几行:

folder1
file3

我想从 dir 中删除列表文件中不可用的所有内容。这意味着这些不会被删除:

folder1
file3.mp4

这些将被删除:

folder2
folder3
file1.mp4
file2.mkv

我试过了:

for f in *; do
    if ! grep -qxFe "$f" list.txt; then
    ....

但这并没有提供我想要的结果。请注意,并非所有文件名都在列表中具有扩展名。

【问题讨论】:

  • 试试find ...conditions... -delete

标签: linux bash shell scripting


【解决方案1】:

另一种选择是避免循环,只需将文件保存在数组中。 使用 mapfile 又名 readarray 这是 bash4+ 功能。

#!/usr/bin/env bash

##: Just in case there are no files the glob will not expand to a literal *
shopt -s nullglob

##: Save the files inside the directory dir (if there are)
files=(dir/*)

##: Save the output of grep in a array named to_delete
mapfile -t to_delete < <(grep -Fvwf list.txt  <(printf '%s\n' "${files[@]}"))

echo rm -rf "${to_delete[@]}"

签出grep -Fvwf list.txt &lt;(printf '%s\n' "${files[@]}")的输出

如果您认为输出正确,请删除rm 之前的echo

【讨论】:

  • q 的打印效果如何?
  • grep 不会有任何输出,这不是这个脚本需要的。
  • 输出似乎是我想要做的。但我意识到我没有列表中的所有文件扩展名。但这个脚本匹配完整的文件名和扩展名。我已经更新了原来的问题,请看一下
【解决方案2】:
cd yourpath/dir/

for f in *; do
    if ! grep -Fxq "$f" /path/list.txt; then
        rm -r "$f"
    else
        printf "Exists -- %s \n" ${f}
    fi
done

如果您想知道(和我一样)-Fxq 在简单的英语中是什么意思:

F: 影响 PATTERN 的解释方式(固定字符串而不是正则表达式)

x: 匹配整行

q: 嘘……最少打印

【讨论】:

    猜你喜欢
    • 2018-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-15
    • 2010-11-12
    • 2013-12-05
    • 1970-01-01
    相关资源
    最近更新 更多