提取口是心非的备份数据

提取口是心非的备份数据

我使用 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

如果我理解正确的话,您的目录包含名为123等的文件(最多可变限制),并且您希望用与该目录同名的文件替换每个目录,并且该文件是文件的串联按数字顺序。

在这个答案中,我将使用桀骜,因为它比 bash 和其他工具的组合更容易使用。您可以将该方法翻译为 sh 和 find (bash 和 GNU find 将比普通 sh 和 POSIX find 更容易)。

首先,要定位目录,点的存在似乎不是一个非常有用的启发式方法:您会错过名称不包含点的文件,并且会找到名称包含点的目录。查找包含数字命名文件的目录似乎更可靠(尽管它并不完美,但没有什么是完美的)。警告:未经测试的代码:

#!/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(而不是仅将其添加到第一个元素)。

相关内容