중복된 백업 데이터 추출

중복된 백업 데이터 추출

Deja Dup을 사용하여 이전 시스템의 일부 백업을 만들었습니다. 현재 배포판에서는 사용할 수 없으므로 방금 데이터를 추출했습니다. 이제 이 데이터를 다시 의미 있게 만들려면 다음과 같이 파일을 분류해야 합니다.

cat ? ?? > file

물론 물음표는 파일 수에 따라 다릅니다.

추출된 데이터 구조는 다음과 같습니다.

some/long/path/to/file/[original_filename_converted_to_folder.extension]/

따라서 파일 이름은 내부에 번호가 매겨진 파일이 있는 폴더입니다(예: 1, 2..20..300.. 등). 파일(현재 폴더)마다 내부에 번호가 매겨진 파일 수가 다릅니다.

그래서 모든 디렉토리를 얻고 싶습니다. 존재하다. 그런 다음 해당 디렉토리에 하위 디렉토리가 없으면 모든 파일을 하나로 묶고 해당 폴더 이름(실제 파일 이름이므로)을 지정하고 한 디렉토리(..)로 전송한 다음 디렉토리를 삭제합니다(디렉토리를 생성하려면 를 사용하십시오). ) 파일 및 파일 이름)

그래서 스크립트를 작성하기 시작했지만 몇 가지 문제에 부딪혔습니다.

directories = "$(find . -type d)"
for i in "$directories"
do
  fdir = "$i"
  rdir = "$(dirname "$i")";
  fname = "$(basename "$i")";
  if [[ "$(basename "$i")" == *"."* ]] then
    cd "$i"
    FILECOUNT="$(find . -type f -maxdepth 1 -printf x | wc -c)"
    DIRCOUNT="$(find . -type d -maxdepth 1 -printf x | wc -c)"
    DIRCOUNT=$(( DIRCOUNT - 1 ))
    if DIRCOUNT == 0 then
      if FILECOUNT != 0 then
        # >> this is the problematic part
        DIGITS = "$(grep -o "[s|S]" <<<"$x" | wc -l)"
          cat "$QUESTIONMARKS" > "$fname"
          mv "$fname" "$rdir" +"/"+ "$fname"+".restored"
          rm *
          cd ..
          rmdir fname
          mv "$fname"+".restored" "$fname"
        # << end of problems
      fi
    fi
  fi
done

그래서 질문은 - 디렉토리의 파일 번호를 기반으로 물음표를 생성하는 방법입니다. 디렉토리에 1자리 파일 번호가 있는 경우 명령은 다음과 같아야 합니다.

cat ? > file

디렉토리에 2자리 파일 번호가 있는 경우:

cat ? ?? > file

3인 경우:

cat ? ?? ??? > file

이해했구나..

그 후 계속해야 할 명령 목록을 작성했는데, 이렇게만 추가해야 합니까, 아니면 ()로 묶어야 합니까?

이런 스크립트에서 CD가 괜찮나요? 문제가 생기지 않을까요?

이를 달성하기 위한 다른 가능한 솔루션이 있습니까?

감사해요.

답변1

내가 올바르게 이해했다면 귀하의 디렉터리에는 1, 2, 3등의 파일이 포함되어 있으며(최대 변수 제한까지) 각 디렉터리를 해당 디렉터리와 동일한 이름을 가진 파일로 바꾸려고 하며 해당 파일은 다음 파일의 연결입니다. 숫자 순서.

이 답변에서는다루기 힘든, bash와 다른 도구를 조합하는 것보다 사용하기가 더 쉽기 때문입니다. 이 방법을 sh 및 find로 변환할 수 있습니다(bash 및 GNU 찾기는 일반 sh 및 POSIX 찾기보다 쉽습니다).

첫째, 점의 존재는 디렉토리를 찾는 데 매우 유용한 경험적 방법이 아닌 것 같습니다. 이름에 점이 포함되지 않은 파일을 놓치고 이름에 점이 포함되지 않은 디렉토리를 찾을 것입니다. 숫자로 명명된 파일이 포함된 디렉터리를 찾는 것이 더 안정적으로 보입니다(비록 완벽하지는 않지만 아무것도 아닙니다). 경고: 테스트되지 않은 코드:

#!/bin/zsh
for dir in **/1(:h); do
  files=($dir/*(Nn:t))
  for ((i=1; i<=$#files; i++)); do
    # if the ith file isn't called i, skip this directory
    if [[ $files[i] != $i ]]; then files=; break; fi
  done
  if [[ -z $files ]]; then continue; fi
  # The directory contains only numbered files, and they're in sequence.
  # Concatenate the files, move the result into place and remove the directory.
  tmp=$(TMPDIR=$dir:h mktemp -d)
  mv -- $dir $tmp &&
  for x in $tmp/$dir:t/$^files; do cat -- $x; done >$tmp/file &&
  mv -- $tmp/file $dir &&
  rm -r $tmp
done

zsh 기능 설명:

  • :t그리고 :h역사 확장 수정자파일의 디렉토리 부분과 기본 이름을 각각 가져옵니다.
  • *(Nn)사용글로벌 예선: n파일 이름을 사전순이 아닌 숫자순으로 정렬하고, N디렉터리가 비어 있으면 오류 대신 빈 배열을 가져옵니다.
  • 이것^매개변수 확장 수정자in은 배열의 각 요소에 $dir/$^files접두사를 추가합니다 (단지 첫 번째 요소에 추가하는 대신).$dir/files

관련 정보