如何删除除作为参数传递的某些特定文件之外的文件?

如何删除除作为参数传递的某些特定文件之外的文件?

任务是编写一个带有 n+1 个参数的 shell 脚本,其中第一个参数是目录,其余的是指定文件,并将删除除指定文件之外的所有文件。

例如打电话rmexcept . '*.jpg' '*.png'

cd $1
for i in “${@:2}”
do 
find . -type f -not -name $i -delete
done 

这是我的尝试。但是,它仅适用于 1 个指定文件(例如rmexcept . '*.jpg')。如果有超过 1 个文件(例如rmexcept . '*.jpg' '*.png'),则所有文件都将被删除。我不知道出了什么问题,因为我相信我已经创建了一个 for 循环。

答案1

试试这个(内嵌评论):

#!/bin/bash                                                                     
set -f     # Prevent e.g. *.txt from being expanded here

dir=$1     # Get the target directory and
shift      # remove from list of args

cmd="find $dir -type f"
while (( "$#" ))              # While there are more arguments left
do
    cmd="$cmd -not -name $1"  # add to not match
    shift                     # and remove from list of arguments
done
cmd="$cmd -exec rm -i {} ;"   # finally execute rm on the remaining matches

echo $cmd  # Print the final find command
$cmd       # And execute it

我添加-irm以便它在删除每个文件之前询问。但当然,你可以调整它。

答案2

  1. 与以下机制相同拉恩凯奥的回答,但作为一个更最小的无变量POSIX外壳函数:

    rmexcept(){ find "$1" $(shift; printf " -not -name %s" ${@}) -exec rm '{}' \; ;}
    

    shell 的printf命令代替for orwhile循环完成主要工作。

  2. 使用bashshell,shift可以用参数扩展来替换:

    rmexcept(){ find "$1" $(printf " -not -name %s" ${@:2}) -exec rm '{}' \; ;}
    

find请注意,如果结果或rm命令长于 返回的数字,则两个函数都不会完成作业getconf ARG_MAX。看:Bash 命令行和输入限制

相关内容