Created
January 20, 2022 22:17
-
-
Save porg/b6b3160f41c5c6ce7ced5a4982d4aa2e to your computer and use it in GitHub Desktop.
Copy modification date from all files of source directory to same named files at destination directory if existing there
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| if [[ -z "$1" || -z "$2" || "$1" == "-h" || "$1" == "--help" ]] ; then | |
| cat <<EOF | |
| USAGE: `basename $0` backupDir targetDir | |
| Loops through all files on root level of backupDir. | |
| For each file in backupDir it tries to find a same named file in targetDir. | |
| - If not found in target (because renamed or removed meanwhile) the file is skipped. | |
| - If found and they have the same modification timestamp nothing is done either. | |
| - If found and the moddates differ the moddate is copied from the backup to the target. | |
| EOF | |
| exit | |
| fi | |
| backupDir=$1 | |
| targetDir=$2 | |
| if [[ ! -d "$backupDir" ]] | |
| then | |
| echo "Error! No directory at path for backupDir:" | |
| echo "$1" | |
| exit | |
| fi | |
| if [[ ! -d "$targetDir" ]] | |
| then | |
| echo "Error! No directory at path for targetDir:" | |
| echo "$2" | |
| exit | |
| fi | |
| backupFiles=$(ls -l1 "$backupDir") | |
| targetFiles=$(ls -l1 "$targetDir") | |
| backupFileCount=$(echo "$backupFiles" | wc -l) | |
| targetFileCount=$(echo "$targetFiles" | wc -l) | |
| echo | |
| echo "Directories to process:" | |
| echo " Backup:$backupFileCount files at: $backupDir" | |
| echo " Target:$targetFileCount files at: $targetDir" | |
| echo | |
| echo "Output format:" | |
| echo | |
| echo " File Name.ext" | |
| echo " Backup's creation date" | |
| echo " Backup's modification date" | |
| echo " Target's modification date" | |
| echo | |
| echo "Symbol at line start of target's moddate:" | |
| echo | |
| echo "√ Backup and target have same moddate. No need to act." | |
| echo "≠ Target's mod-date differs. --> Gets restored from backup." | |
| echo "x No same named file in target directory anymore." | |
| echo | |
| echo | |
| echo "Copying modification timestamps..." | |
| echo | |
| echo "$backupFiles" | while read file | |
| do | |
| echo " $file" | |
| backupFileCreation=$(GetFileInfo -d "$backupDir/$file") | |
| backupFileModification=$(GetFileInfo -m "$backupDir/$file") | |
| echo " $backupFileCreation" | |
| echo " $backupFileModification ───┐" | |
| if [[ -f "$targetDir/$file" ]] ; then | |
| targetFileModification=$(GetFileInfo -m "$targetDir/$file") | |
| if [[ "$backupFileModification" == "$targetFileModification" ]] ; then | |
| echo "√ $targetFileModification √ ─┘" | |
| else | |
| SetFile -m "$backupFileModification" "$targetDir/$file" | |
| echo "≠ $targetFileModification └───> Restored from backup √" | |
| fi | |
| else | |
| echo "x Not in target dir ! ─┘" | |
| fi | |
| echo | |
| done |
@porg Actually, by demand, I did just port to using gdate, gstat, and gtouch so that there's no reliance on the deprecated GetFileInfo and SetFile tools (and now works for Linux or wherever the GNU coreutils tools are supported)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Oh actually I did just find a subtle bug in our implementations. My use case is to restore the modification dates of directories, not plain files. But the key here is that the modification dates of deeper subdirectories need to be updated before those of parent subdirectories. That's because any
SetFilewould not only restore the modification date of a given file or subdirectory but also update the modification date of the parent directory since that's the normal expected behavior of filesystems: if you modify the content of a directory, the directory's modification date is updated. If the restore is done in the wrong order, then any restores would later be overwritten by these automatic updates.As I said, the solution is to update deep subdirectories before parent directories. Since I'm using the
findcommand, for my script that means I need to use the-depthflag, which means "depth-first traversal". I've just fixed my script. For you it would mean figuring out a way to makelsoutput in the right order, perhaps by reversing the order by usingtac. (Btw, you were asking about "innovations"; I usefindinstead oflsso that my script can stream an arbitrary number of files and folders. Withlsand bash arrays, you may run into hard-coded and/or memory limits).Of course for many users, they only care about the modification dates of files and not directories, so this subtlety wouldn't matter for them.