从bash列表中过滤出比另一个文件更旧的文件

时间:2018-06-20 15:22:24

标签: bash

给出文件名列表,是否有办法从列表中删除与早于另一个文件的文件相对应的名称?

例如,如果我有一个字符串"a b c",并且文件a早于文件d,但是bc却不是,我想要将字符串转换为"b c"

编辑,因为人们要求提供具体信息:

我想减少这段bash脚本中的代码重复:

for f in $(ls | grep '.json$'); do
  base=$(basename $f .json)
  regex=".*/${base}_[0-9]\{3\}-[0-9]\{3\}\.dat"
  if [ -z "$(find dat -regextype sed -regex ${regex})" ] || \
     [ -n "$(find dat -regextype sed -regex ${regex} -not -newer $f)" ] || \
     [ -n "$(find dat -regextype sed -regex ${regex} -not -newer ../bin/vars)" ]
  then
    echo $f
    ../bin/vars $f -o dat/$base \
      -b 200 250 300 350 400 450 500
  fi
done

1 个答案:

答案 0 :(得分:3)

有一个比较运算符-nt(比“新”)来比较两个文件。如果您有以下文件:

-rw-r--r-- 1 benjamin staff   0 Jun 20 11:30 a.json
-rw-r--r-- 1 benjamin staff   0 Jun 20 11:34 b.json
-rw-r--r-- 1 benjamin staff   0 Jun 20 11:34 c.json
-rw-r--r-- 1 benjamin staff   0 Jun 20 11:32 d.json

然后您可以按以下方式使用它:

$ for f in {a,b,c}.json; do [[ $f -nt d.json ]] && echo "$f"; done
b.json
c.json

包装在一个函数中,该函数将引用文件作为第一个参数,并将文件名列表作为其余参数:

filterfiles () {
    local filtered
    for f in "${@:1}"; do
        [[ $f -nt $1 ]] && filtered+=("$f")
    done
    echo "${filtered[@]}"
}

使用方式

$ filterfiles d.json {a,b,c}.json
b.json c.json

或者,如果您只想知道是否有至少一个文件比参考文件新(如注释中所提及):

filterfiles () {
    for f in "${@:1}"; do
        [[ $f -nt $1 ]] && return 0
    done
    return 1
}

现在,您可以检查函数的返回值:

if filterfiles d.json {a,b,c}.json; then echo "Array contains newer file"; fi