文件恢复/恢复后任务

出自 ArchWiki
注意: 为了加快访问已恢复或还原的文件,您可以使用 shake 工具来对它们进行碎片整理。

仅列出校验和唯一的文件

注意
  • 要仅列出 photorec 可以恢复原始名称的文件,您可以在 awkprint 之前添加 if(index(A,"_") != 0)。您也可以在已创建的文件上使用 awk 作为独立命令,以仅列出您需要的文件名或扩展名。
  • 要仅列出扩展名,您可以在 awk 中使用 D=B;gsub(/[^*\.]*\./,"",D),这将删除直到最后一个 . 点的所有内容,从而仅显示 gz 扩展名,即使是 tar.gz 扩展名也是如此。或者您可以使用 sub 而不是 gsub,这将仅删除文件名中第一个点之前的内容。

当文件被恢复时,可能其中许多文件具有相同的 哈希和,通过创建一个包含唯一文件的列表,其中仅包含找到的重复文件之一,您将通过使用存储在其中的文件名和路径,加快使用其他实用程序收集有关文件的额外信息。

find -type f -print0 | \
 xargs -0  md5sum | \
 awk '// {Count[$1]++;
 if( Count[$1] == 1 ){C=substr($0,index($0,"./"));A=$0;sub(/^.*\//,"",A);B=substr(A,index(A,"_")+1);HASHsum=$1;
 print A"|"B"|"C"|"HASHsum}}' 

这将在屏幕上打印出结果,模式为:文件名|恢复的文件名|文件完整路径|校验和

f851733136_WindowMaker_Dockapps.pdf|WindowMaker_Dockapps.pdf|./f851733136_WindowMaker_Dockapps.pdf|272cc4fcdc8027e3b8b53318f08f3f01

清理和排序文件名

为了使目标文件名更 bash 友好,您可以删除特殊符号、空格,并按第二列排序,以便更好地查看具有不同校验和的重复名称。对于重复的文件名,将在 restored_filename 前面添加一个数字,并使用 ¤ 作为分隔符。该脚本将使用上面脚本创建的文件,并将结果打印到 stdout

clean_and_sort.sh
if [ ! -z "$1" ];then
  awk -F"|" '{B=$2;
   gsub(/\(/,"",B);gsub(/\)/,"",B);
   gsub(/!/,"",B); gsub(/?/,"",B);
   gsub(/\[/,"",B);gsub(/\]/,"",B);
   gsub(/{/,"",B); gsub(/}/,"",B);
   gsub(/&/,"",B); gsub(/=/,"",B);
   gsub(/\^/,"",B);gsub(/~/,"",B);
   gsub(" ","",B) ;gsub(/#/,"",B);
   gsub(/\"/,"",B);gsub(/;/,"",B);
   gsub(/\\/,"",B);gsub(/\//,"",B);
   sub(/-*/,"",B); sub(/+*/,"",B);
   print $1" | "B" | "$3}' "$1" | \
  sort --field-separator=\| -s -d -k 2  \
awk -F'|' '{B=$2;Count[B]++;sub(/ */,"",B);if( Count[$2] == 1 ){print $1"|"B"|"$3}else{print $1"|"Count[$2]-1"¤"B"|"$3"|"$4} }'
else echo 'Path to file is missing!'
fi

带有特殊符号的文件名,特别是如果文件名以它们开头,则更难以使用 mvcp 等命令进行管理,而无需使用引号或反斜杠 \。但是,如果您想保留有关它们的信息,则可以使用 HTML 十六进制代码 来替换它们,而不是全部删除。

Photorec

创建包含数组数据的文件

在本例中,xdg-mime 用于收集有关 MIME 类型的信息,但 file --mime-type -bfile -i -b 命令与 xdg-mime query filetype 命令产生相同的输出,只是细节多少有所不同。此脚本将收集更多关于文件的附加信息到 info-mime-size-db.txt 中。将脚本放在您在 photorec 中使用的目标目录中,使其可执行,并使用来自上面描述的具有唯一校验和的列表中的文件路径。例如:awk -F" | " '{system("start-collect-file-info.sh "$3" "$1" "$2)}' file_list-unique_checksums

start-collect-file-info.sh
#!/bin/bash
if [ ! -z "$1" ] && [ ! -z "$2" ] && [ ! -z "$3" ]; then
if [ -f "$1"  ]; then
echo "$1"
echo "$(file "$1" -F"|"  )'|'$(xdg-mime query filetype "$1")'|'$(du -h "$1" |awk '{print $1}' )|$2|$3" >> info-mime-size-db.txt
else
echo The « "$1" » is not a valid file name.
fi
fi

该脚本将构建一个文件,模式为 文件路径/文件名 | 文件信息 | MIME 类型 | 大小 | 文件名 | 恢复的文件名,这是一个示例:./recup_dir.1/f872690288_image.jpg|JPEG image data, JFIF standard 1.01|image/jpeg|24K|f872690288_image.jpg|image.jpg

恢复后任务

这将帮助您更好地理解脚本,并基于它创建您自己的脚本。您也可以将所有必要的部件放在一个脚本中,修改要搜索文件的模式并运行它。您需要创建一个名为 info-mime-size-db.txt 的数据库文件,其中包含有关文件的信息。

警告
  • 移除 cpmkdir 命令前面的 echo 命令,否则脚本将仅显示将要执行的操作,而不会将任何内容恢复到目标位置,请进行试运行。使用 echo 命令可以很好地验证文件名和目标位置的设置是否正确。
  • 这些脚本仅是从 photorec 创建的文件夹中恢复文件的示例,请小心使用!

脚本头部

这是一个简单的检查,用于检查 info-mime-size-db.txt 是否存在于当前目录中,以防止脚本其余部分可能出现的错误。

#!/bin/bash
if [ -f info-mime-size-db.txt ]; then echo The file info-mime-size-db.txt exists continuing... ;
  else 
  echo Error!! the info-mime-size-db.txt file cannot be found;exit 1; 
fi

起始变量

CountAll="0"
CountToLimit="0"
BaseSubDirName="MyRestoredFiles"
Destination="$HOME/NameOfBaseFolder/${BaseSubDirName}-MoreDetailsInFolderName/"
NewDirNumber="0"
CountToLimit="0"

填充数组

警告: 数组通过从 info-mime-size-db.txt 文件读取数据来填充。否则,脚本将无法正常工作!
使用 while 循环

这里将简要示例说明如何通过使用 bash 标准表达式 而不是 awkgrepsed 来加速从带有模式的文件中填充数组。ArrayOfFiles 数组将包含文件的完整路径,而 ArrayOfsorted 将包含 photorec 恢复的原始名称,但不包含随机生成的部分。

WhileArray=0;
while read i; do
if [[ "$i" =~ "gif" ]]||[[ "$i" =~ "jpeg" ]];then
ArrayOfFiles[WhileArray]=${i/'|'*/}
ArrayOfsorted[WhileArray]=${i/[^*|]*|/}
WhileArray=$((WhileArray+1));
fi;
done <  info-mime-size-db.txt
echo done, the array is full

用于恢复的循环

这是管理文件恢复的脚本的最后一部分。当目标子目录中的文件数量达到限制时,它将在目标文件夹中创建一个新的编号子目录,并继续将文件复制到那里。

SizeOfArray=${#ArrayOfFiles[@]}
while [  "${SizeOfArray}" != "${CountAll}" ]; do

IfExist="${Destination}${BaseSubDirName}${NewDirNumber}"
if [ ! -d "${IfExist}" ]; then echo mkdir -v "${IfExist}" -p;fi

CountToLimit=$((CountToLimit+1 ))
FileName=${ArrayOfsorted[CountAll]}
    if [ $CountToLimit -gt 25 ]; then
CountToLimit="0"
NewDirNumber=$((NewDirNumber+1))
fi;
NewDestination="$IfExist"

echo cp -fv "$PWD/${ArrayOfFiles[CountAll]}" "${IfExist}${FileName}"
CountAll=$((CountAll+1))
done
注意: 为了在文件名或目标目录名称中添加更多关于文件的具体细节,您需要使用外部程序收集关于它们的信息,例如,对于图像分辨率:feh feh -l "${ArrayOfFiles[$CountAll]}" | tail -1 | awk '{print $3"x"$4}'imagemagick identify ${ArrayOfFiles[$CountAll]} | awk '{print $3}'

文件数量少时已足够

如果同一扩展名的文件不多,那么使用类似 find -name *.xcf -exec copy "{}" $HOME/Desktop \; 这样的命令就足够了,为了避免目标文件夹的过载,您可以计算找到多少文件 find -type f -name *xcf | wc -l

注意: photorec 工具在一个文件夹中最多存储 500 个恢复的文件。