bashを使用して不完全なファイルを元のファイルに置き換える方法

bashを使用して不完全なファイルを元のファイルに置き換える方法

私は2つのディレクトリを持っていますが、どちらも異なるサブディレクトリを持っています。

抽出されたファイルの「半分」を.mkv別のプログラムからインポートしました。

秒には、.mkv完全に抽出された元のファイルが含まれています。


破損した.mkvファイルを元のファイルに置き換えるためにbashスクリプトを作成しようとしています。両方のディレクトリのファイル名は同じですが、サブディレクトリとファイルサイズは異なります。


find、およびに関連する多くのfdupesソリューションを作成または変更してみましたgrep

しかし、私はそれを動作させることはできません。誰でも私を助けることができますか?


不完全な例

#!/bin/bash

dirname1=/mnt/raid1/dir1
dirname2=/mnt/raid1/dir2
find $dirname1 -name '*.mkv'
while read fileName
do
find $dirname2 -type f | grep "$fileName"
done

答え1

ファイル名が同じ場合は、単に以下を使用してくださいmv

# traverse the original's directory
for o in original/*/*.mkv; do
  # traverse the corrupted's directory
  for c in corrupted/*/*.mkv; do 
    # if a corrupted file has the same name as an original's
    # perform the `mv` command replacing the former
    if [[ "$(basename "$o")" = "$(basename "$c")" ]]; then
      mv -- "$o" "$c"; 
    fi
  done
done

二重ダッシュは次のことを--意味します。:

ガイドライン10:オプションではない最初の--パラメーターは、オプションの終わりを示す区切り文字として許可する必要があります。後続の引数は、「-」文字で始まってもオペランドとして処理する必要があります。

-iファイルを上書きする前に質問を表示するオプションを使用できます。何千ものファイルがある場合、これは問題になる可能性があります。

mv -i -- "$o" "$c"
mv: overwrite 'corrupted/<sub dir>/filename.mkv'?

メモ:一般的に言えば、上書き/削除操作を実行する前にデータをバックアップすることをお勧めします。

答え2

zsh代わりに使用してくださいbash

#! /bin/zsh -
zmodload zsh/stat || exit

orig_dir=/mnt/raid1/dir1
incomplete_dir=/mnt/raid1/dir2

typeset -A where size

for f in $orig_dir/**/*.mkv(ND.); do
  stat -A s +size -- $f || continue
  if (( $+where[$f:t] )); then
    print -ru2 -- "$f:t is found in more than one place ($where[$f:t] and $f at least)!"
    exit 1
  fi
  where[$f:t]=$f size[$f:t]=$s
done

# for dry-run (comment out when happy)
cp() (PS4='Would run'; set -x; : cp "$@")

ret=0
for f in $incomplete_dir/**/*.mkv(ND.); do
  stat -A s +size -- $f || continue
  if (( $size[$f:t] > $s )); then
    cp -- $where[$f:t] $f || ret=$?
  fi
done
exit $ret

(検証されていません)。

ファイル全体をコピーするのではなく、ファイルの欠落部分のみを追加するには、次のようにします。

zmodload zsh/system
resume() {
  {
    sysseek -w end -u 1 0 &&
      sysseek -w start -u 0 $(( systell(1) )) &&
      cat
  } < $1 1<> $2
}

resume上記の代わりに使用されますcp --

関連情報