File recovery on Linux is done via a powerful tool called PhotoRec. It not only recovers photos and videos. It can do a deep scan and detect these filetypes too (some would be unselected by default and you need to select it):
It can also detect a custom file signature you specify.
![]() |
PhotoRec |
Install testdisk first (it also contains photorec):
sudo apt update; sudo apt -y install testdisk
Run testdisk as: sudo testdisk
Run photorec as: sudo photorec
Running a PhotoRec scan on a 32GB SD Card took 6 hours, and it recovered many files that were thought were deleted. The problem with PhotoRec, is that it recovers files with no regard to which folder it is present in, and just recovers files into folders it generates, named "recup". TestDisk on the other hand, can scan the disk and recover them with their original file and folder names. But it would not recover as many files as PhotoRec does. I suggest using both software, based on what your recovery needs are.
Since you'd be running the program using sudo, after file recovery, the file and folder ownership of the recovered data will be root. So to convert it to the ownership of the current Linux user, use this script:
#!/bin/bash
# Get the real user who invoked the script, even when using sudo
REAL_USER=$(logname) # or `SUDO_USER` if running via `sudo`
REAL_GROUP=$(id -gn "$REAL_USER")
# Define the target directory (default is current directory)
TARGET_DIR="${1:-.}"
# Change ownership recursively
sudo chown -R "$REAL_USER:$REAL_GROUP" "$TARGET_DIR"
echo "Ownership of all files and folders in '$TARGET_DIR' changed to $REAL_USER:$REAL_GROUP."
And to copy all files from all recup folders into the folder containing all recup folders, use this script:
#!/bin/bash
# Set the target directory (the main folder)
TARGET_DIR="${1:-.}"
# Ensure the target directory exists
if [ ! -d "$TARGET_DIR" ]; then
echo "Error: Target directory does not exist."
exit 1
fi
# Move into the target directory
cd "$TARGET_DIR" || exit
# Find all files in subdirectories and move them
find . -mindepth 2 -type f | while IFS= read -r file; do
filename=$(basename "$file")
dirname=$(dirname "$file")
# Check if a file with the same name exists in the main folder
if [ -e "$filename" ]; then
counter=1
new_filename="${counter}_$filename"
# Generate a unique filename
while [ -e "$new_filename" ]; do
counter=$((counter + 1))
new_filename="${counter}_$filename"
done
# Rename and move the file
mv "$file" "$new_filename"
echo "Renamed and moved: $file -> $new_filename"
else
# Move the file directly
mv "$file" "$filename"
echo "Moved: $file -> $filename"
fi
done
echo "All files have been moved successfully!"
find . -mindepth 1 -type d -empty -delete
echo "Deleted empty subfolders"
# Delete non empty subfolders
#find . -mindepth 1 -type d -exec rm -r {} +
To run the scripts above, copy them into a file named `filename.sh`, and make it executable with:
chmod +x filename.sh
Then run it as:
./filename.sh