Last active
April 2, 2020 12:37
-
-
Save torson/6d5d4a4e09e93250069c903d9f59d91d to your computer and use it in GitHub Desktop.
Copy and position files into another folder by renaming the copied files based on their timestamp
This file contains 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
#!/usr/bin/perl | |
# This script takes the files from the inbound folder and copies them | |
# into the base folder and in the process positions each inbound file | |
# between 2 base files - between the older and the newer base file by | |
# renaming it accordingly (using the older file as the 1st part and the | |
# inbound file as the 2nd part of the new name) | |
# Scenario: | |
# You configured your phone to use SD card for storing pictures. | |
# Then at some point you remove the SD card, put it back in and the phone | |
# started using the local storage without you realising, so then you | |
# have old photos on the SD card and new photos on internal storage with | |
# low IDs in the filenames so you can't just copy them to SD card. After | |
# setting your phone back to use SD card use this script to combine the folders | |
# Copy both folders to your computer and run this script like this: | |
# ./folders_merge_by_timestamp.pl -b=<sdcard_folder> -i=<internal_storage_folder> | |
# Pictures from internal storage folder will be copied into the sdcard folder | |
# and positioned there correctly between those files by using their timestamp. | |
# You can run this script multiple times | |
use strict; | |
use warnings; | |
my $help = ""; | |
my $inErr = ""; | |
$help .= "\nWRONG ARGUMENT INPUT! Exiting.."; | |
$help .= "\n\nUsage:\n$0 [OPTIONS]\n\nOPTIONS:\n"; | |
$help .= "\n\t-b=[base folder path] "; | |
$help .= "\n\t-i=[inbound folder path] "; | |
$help .= "\n\n\tEXAMPLE: \n\t$0 -b=sdcard_images -i=rootfs_images"; | |
$help .= "\n\n"; | |
## ARGUMENTS FETCH | |
my $baseDirPath; | |
my $inboundDirPath; | |
for (my $iargv=0; $iargv<=$#ARGV; $iargv++) { | |
my @param; | |
if ($ARGV[$iargv] =~ m/^\-b\=/i) { | |
@param = split(/=/, $ARGV[$iargv]); | |
$baseDirPath = $param[1]; | |
$baseDirPath =~ s/\/$//; | |
$baseDirPath .= '/'; | |
} | |
elsif ($ARGV[$iargv] =~ m/^\-i\=/i) { | |
@param = split(/=/, $ARGV[$iargv]); | |
$inboundDirPath = $param[1]; | |
$inboundDirPath =~ s/\/$//; | |
$inboundDirPath .= '/'; | |
} | |
else { | |
print $help; | |
exit; | |
} | |
} | |
if (scalar(@ARGV)==0) { | |
$inErr .= "\n Error! No input arguments. \n"; | |
} | |
if ($inErr ne "") { | |
print $inErr . "\n" .$help; | |
exit; | |
} | |
my @baseDirContent = sort(readDir($baseDirPath)); | |
my @inboundDirContent = sort(readDir($inboundDirPath)); | |
if (scalar(@baseDirContent)==0) { | |
print "ERROR! Base folder empty.. exiting"; | |
exit 1; | |
} | |
if (scalar(@inboundDirContent)==0) { | |
print "ERROR! Inbound folder empty.. exiting"; | |
exit 1; | |
} | |
my $baseFilePrev; | |
my $baseFilePathPrev; | |
my $cmd; | |
my %doneFiles; | |
my %skipFiles; | |
my %printSkippingDone; | |
# gathering files that have been copied in a previous run | |
foreach my $baseFile (@baseDirContent) { | |
foreach my $inboundFile (@inboundDirContent) { | |
if ($baseFile =~ m/_$inboundFile$/) { | |
$skipFiles{$inboundFile}++; | |
} | |
} | |
} | |
foreach my $baseFile (@baseDirContent) { | |
my $baseFilePath = $baseDirPath.$baseFile; | |
if ( -d $baseFilePath ) { | |
next; | |
} | |
if ($baseFilePathPrev) { | |
foreach my $inboundFile (@inboundDirContent) { | |
if ($skipFiles{$inboundFile}) { | |
if (!($printSkippingDone{$inboundFile})) { | |
print "skipping $inboundFile, probably already copied in a previous run..\n"; | |
$printSkippingDone{$inboundFile}++; | |
$doneFiles{$inboundFile}++; | |
} | |
next; | |
} | |
if ($doneFiles{$inboundFile}) { | |
next; | |
} | |
my $inboundFilePath = $inboundDirPath.$inboundFile; | |
if ( -d $inboundFilePath ) { | |
next; | |
} | |
if ( | |
(stat($inboundFilePath))[9] > (stat($baseFilePathPrev))[9] | |
&& (stat($inboundFilePath))[9] <= (stat($baseFilePath))[9] | |
) { | |
# insert the inbound file between the older and the newer base file | |
# print "baseFilePathPrev: $baseFilePathPrev \n"; | |
# print "inboundFilePath: $inboundFilePath \n"; | |
# print "inboundFile: $inboundFile \n"; | |
my $newFileName = $baseFilePrev; | |
$newFileName =~ s/\.[^.]+$/_$inboundFile/g; | |
# print "newFileName: $newFileName \n"; | |
# print "baseFilePath: $baseFilePath \n"; | |
$cmd = "cp $inboundFilePath $baseDirPath$newFileName"; | |
print "$cmd\n"; | |
print `$cmd`; | |
my ($READTIME, $WRITETIME) = (stat($inboundFilePath))[8,9]; | |
utime($READTIME, $WRITETIME, $baseDirPath.$newFileName); | |
$doneFiles{$inboundFile}++; | |
} | |
} | |
} | |
$baseFilePrev = $baseFile; | |
$baseFilePathPrev = $baseFilePath; | |
} | |
# copy the rest of the inbound files, as they are either younger | |
# or older than any file in base folder | |
foreach my $inboundFile (@inboundDirContent) { | |
my $inboundFilePath = $inboundDirPath.$inboundFile; | |
if ( ! -d $inboundFilePath ) { | |
if (!($doneFiles{$inboundFile})) { | |
$cmd = "cp $inboundFilePath $baseDirPath$inboundFile"; | |
print "$cmd\n"; | |
print `$cmd`; | |
my ($READTIME, $WRITETIME) = (stat($inboundFilePath))[8,9]; | |
utime($READTIME, $WRITETIME, $baseDirPath.$inboundFile); | |
} | |
} | |
} | |
sub readDir { | |
my ($dirPath) = @_; | |
my @dirContent; | |
opendir(DIR, $dirPath) or print "Cannot open directory $dirPath\n"; | |
@dirContent = readdir(DIR); | |
closedir(DIR); | |
# remove . and .. | |
shift @dirContent for 1..2; | |
return @dirContent; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment