找到 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/

相關內容