应删除提供的文件数量的脚本仅删除一个文件

应删除提供的文件数量的脚本仅删除一个文件

我相当原始的 shell 脚本有两个参数:第一个是位置,第二个是需要删除的文件数量。由于某种原因,即使我给出了示例 3 的参数,它也只删除了一个文件。代码:

#!/bin/bash
for i in {0..$2}
do
find $1 -type f | head -1 | xargs rm
done

更新 此代码似乎由于某种原因删除了两个文件:

#!/bin/bash
for i in eval {0..$2}
do
find "$1" -type f | head -1 | xargs rm
done

答案1

这是一个优先级问题。括号扩展内的变量不会被解释,因为括号被求值变量被扩展。为了说明这一点,请运行以下命令:

$ var=3
$ set -x
$ echo {0..$var}
+ echo '{0..3}'
{0..3}

正如您所看到的,echo {0..$var}被扩展为echo '{0..3}',因此文字字符串{0..3}并不0 1 2 3像您所期望的那样。

解决这个问题的一种方法是使用eval

$ eval echo {0..$var}
+ eval echo '{0..3}'
++ echo 0 1 2 3
0 1 2 3

所以你可以将脚本更改为:

#!/bin/bash
for i in $(eval echo {0..$2})
do
    find "$1" -type f | head -1 | xargs rm
done

但这既危险又丑陋。这样会更好:

#!/bin/bash
for((i=0;i<=$2;i++))
do
    find "$1" -type f | head -1 | xargs rm --
done

带有一些基本安全测试并且可以处理任意文件名(包括名称中带有换行符的文件)的更好版本(如果您使用的是 GNU 工具)是:

#!/bin/bash

if [[ $# -ne 2 ]]; then
  echo "We need 2 arguments!"
  exit
fi
if [[ ! $2 =~ ^[0-9]+$ ]]; then
  echo "The second argument ('$2') must be a number!"
  exit;
fi

for((i=0;i<=$2;i++))
do
  find "$1" -type f -print0 | head -z -n 1 | xargs -0 -I {} rm -- {}
done

相关内容