循环遍历模式以在bash find命令中使用

时间:2018-01-09 21:18:01

标签: regex bash loops find substitution

我正在尝试编写一个简单的bash脚本来查看目录并删除与模式匹配的文件的所有版本(最新的2除外)。这个命令效果很好:

find . -type f -name 'a.*.log' -printf '%T@\t%p\n' \
  | sort -t $'\t' -g \
  | head -n -2 \
  | cut -d $'\t' -f 2- \
  | xargs rm -f

这将采用以下文件:a.1.log,a.2.log和a.3.log,并删除a.1.log(假设它是时间戳最旧的)。文件名的版本部分是一个哈希值,因此不按数字顺序排列(为简单起见我改了它)。

所以,我想要做的是循环一组不同的模式,并将每个模式提供给上面的find命令。我已将此示例的脚本简化为:

#!/bin/bash
FILES="a.*.log
b.*.log
c.*.log"

for f in $FILES
do
    echo "Processing $f"
    find . -type f -name "$f"
done

我正在运行此目录的目录包含以下文件:

a.1.log, a.2.log, a.3.log, b.1.log, b.2.log, b.3.log, c.1.log, c.2.log, c.3.log

我从上面的脚本得到的输出是:

Processing a.1.log
./a.1.log
Processing a.2.log
./a.2.log
Processing a.3.log
./a.3.log
Processing b.1.log
./b.1.log
Processing b.2.log
./b.2.log
Processing b.3.log
./b.3.log
Processing c.1.log
./c.1.log
Processing c.2.log
./c.2.log
Processing c.3.log
./c.3.log

我需要的是输出看起来像这样:

Processing a.*.log
./a.1.log
./a.2.log
./a.3.log
Processing b.*.log
./b.1.log
./b.2.log
./b.3.log
Processing c.*.log
./c.1.log
./c.2.log
./c.3.log

我尝试过使用数组而不是循环遍历字符串,转义文件模式,使用find中的单引号和双引号等等...但我不能简单地将模式替换为查找。如果我手动单独运行查找,它会为我提供我正在寻找的输出:

$ find . -type f -name "a.*.log"
./a.1.log
./a.2.log
./a.3.log
$ find . -type f -name "b.*.log"
./b.1.log
./b.2.log
./b.3.log
$ find . -type f -name "c.*.log"
./c.1.log
./c.2.log
./c.3.log

我找不到任何人循环遍历模式集合并将其替换为命令的示例。任何帮助都会很棒。

感谢。

1 个答案:

答案 0 :(得分:2)

你遇到的问题是没有引号变量被拆分但是文件通配也会发生,这可以使用shell选项noglob set -f,或使用数组并使用双引号来避免:

files=( 'a.*.log' 'b.*.log' 'c.*.log' )

for f in "${files[@]}"; do
...