冗長バックアップデータの抽出

冗長バックアップデータの抽出

Deja Dupを使用して以前のシステムのいくつかのバックアップを作成しました。現在のディストリビューションでは利用できないので、データを抽出しました。このデータを意味のあるものにするには、次のようにファイルを分類する必要があります。

cat ? ?? > file

もちろん、疑問符はファイルの数によって異なります。

抽出されたデータ構造は次のとおりです。

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

したがって、ファイル名は、内部に番号が付けられたファイルを含むフォルダです(たとえば、1、2..20..300..など)。ファイル(現在のフォルダ)ごとに、内部に番号が付けられたファイルの数が異なります。

だからすべてのディレクトリを取得したいと思います。存在する。その後、そのディレクトリにサブディレクトリがない場合は、すべてのファイルを1つにまとめてそのフォルダ名(実際のファイル名なので)を指定し、1つのディレクトリ(..)に転送してディレクトリを削除します(ディレクトリを作成するには使用します)。 ) ファイルとファイル名)

だから私はスクリプトを書き始めましたが、いくつかの問題に遭遇しました。

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

関連情報