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 --.

관련 정보