Skip to content

Instantly share code, notes, and snippets.

@torson
Last active April 2, 2020 12:37
Show Gist options
  • Save torson/6d5d4a4e09e93250069c903d9f59d91d to your computer and use it in GitHub Desktop.
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
#!/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