找到 2 个具有相似名称的文件并将它们移动到新位置

找到 2 个具有相似名称的文件并将它们移动到新位置

我有一个带有监视文件夹的系统,人们/公司可以通过 FTP 或 SMB 上传新文件。在此监视文件夹中,他们应始终上传 2 个文件:1 个媒体文件,其前缀名称ABC*.mxf为“*”且始终带有数字。另一个是相同的文件名,但带有.xml扩展名。

示例:上传的文件为:ABC0001.mxf、ABC0001.xml

如果上传了第二个文件 ABC0002.xml,但 ABC0002.mxf 尚未上传,或未完成,则不应移动 ABC0002.xml 文件。仅当 ABC*.mxf 和 A​​BC*.xml 都存在匹配名称且时间长度为 5 分钟或更早时,才应移动它们。

我需要创建一个脚本来查找这 ​​2 个相同的文件(按名称而不是扩展名),并且仅在修改时间 (mmin) 早于 5 分钟时才移动它们。因此仅移动已完成的文件。

另外我必须说,不同的供应商可以同时上传多个文件。公司 1 制作 ABC0001.mxf + .xml,公司 2 制作 ABC0100.mxf + .xml,公司 3 制作 ABC1003.mxf + .xml。并非全部同时完成。

我已经开始使用部分脚本,但我正在努力处理匹配的名称部分。


SOURCEDIR="/dir/to/source"
DESTDIR="/destination/dir"

for FOUND in `find $SOURCEDIR/AutoIngest -maxdepth 1 \
    -type f -name ^ABC* -mmin +5 `;     
do     
    mv "$FOUND" "$DESTDIR/"    
done

编辑:将文件名从 ABC* 更改为 ABC*.mxf,因为媒体文件始终具有 .mxf 扩展名。并添加了文件上传示例。

答案1

最简单的方法取决于您对用户的信任程度。如果您不需要测试这两个文件是否存在或名称是否正确或其他任何内容,您甚至不需要脚本。您可以通过简单的操作来做到这一点find

find /dir/to/source -name "ABC*" -mmin +5 -exec mv {} /destination/dir \;

如果您需要确保 i) 两个文件都存在并且 ii) 两者的修改时间至少为 5 分钟前,在 GNU 系统上,您可以执行以下操作:

#!/usr/bin/env bash

SOURCEDIR="/dir/to/source"
DESTDIR="/destination/dir"

for f in "${SOURCEDIR}"/*.xml; do
    ## Make sure the file exists and is a regular file (or symlink to regular file),
    ## and that its modification date is at least 5 minutes ago
    [ -f "$f" ] && [ "$(( $(date +%s) - $(stat -c %Y "$f") ))" -ge 300 ] || continue

    ## Do the same for a file of the same name but with the .mxf extension.
    mxf="${SOURCEDIR}/$(basename "$f" .xml).mxf";
    [ -f "$mxf" ] && [ "$(( $(date +%s) - $(stat -c %Y "$no_ext") ))" -ge 300 ] || continue

    ## We will only get to this point if all of the above tests were successful
    echo mv -v "$f" "$mxf" "$DESTDIR"
done

答案2

在 GNU 系统上:

SOURCEDIR="/dir/to/source"
DESTDIR="/destination/dir"
TIMESTAMP_MINDIFF=300

timestamp="$(date +%s)"
find "$SOURCEDIR/AutoIngest" -maxdepth 1 -type f -name 'ABC*' ! -name '*.xml' |
  while IFS= read -r file; do
    xmlfile="${file}.xml"
    test -f "$xmlfile" || continue
    ts_file="$(date --reference="$file" +%s)"
    ts_xmlfile="$(date --reference="$xmlfile" +%s)"
    if [ "$((timestamp-ts_file))" -gt "$TIMESTAMP_MINDIFF" ] &&
       [ "$((timestamp-ts_xmlfile))" -gt "$TIMESTAMP_MINDIFF" ]; then
      echo mv "$file" "$xmlfile" "$DESTDIR/"
    fi
  done

echo如果输出是您想要的,请删除。

答案3

zsh

cd /dir/to/source || exit
files=(ABC*(N.mm+5))
for f ($files[(k)*.xml]) {
   (($files[(I)$f:r])) && print -r mv -v -- $f $f:r /destination/dir/
}

(如果高兴则删除 print -r)。

或者避免mv多次调用:

cd /dir/to/source || exit
files=(ABC*(N.mm+5))
tomove=()
for f ($files[(k)*.xml]) {
   (($files[(I)$f:r])) && tomove+=($f $f:r)
}
print -r mv -- $tomove /destination/dir/

相关内容