似た名前の2つのファイルを見つけて新しい場所に移動する

似た名前の2つのファイルを見つけて新しい場所に移動する

監視フォルダを備えたシステムがあり、個人や企業は FTP または SMB 経由で新しいファイルをアップロードできます。この監視フォルダには、常に 2 つのファイルをアップロードする必要があります。1 つは、プレフィックス名が でABC*.mxf、常に '*' の番号が付いたメディア ファイルです。もう 1 つは、ファイル名は同じですが、拡張子が付きます.xml

例: アップロードされたファイル: ABC0001.mxf、ABC0001.xml

2 番目のファイル ABC0002.xml がアップロードされているが、ABC0002.mxf がまだアップロードされていないか、完了していない場合は、ABC0002.xml ファイルはまだ移動しないでください。ABC*.mxf と ABC*.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

編集: メディア ファイルには常に .mxf 拡張子が付いているため、ファイル名を ABC* から ABC*.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/

関連情報