I have a folder of videos (Mac OSX Yosemite) for which I need to change the Created Date by adding 2180 days to the existing Created Date.
Using SetFile from Terminal I am able to manipulate the Created Date, for example I can set it as equivalent to the Modified Date of the same file:
SetFile -d "$(GetFileInfo -m /Users/myfilename.mov)" /Users/myfilename.mov
However, if I try to add the ‘Add 2180 days’ part it stops working:
SetFile -d "$(GetFileInfo -d /Users/myfilename.mov) +2180 days" /Users/myfilename.mov
I suspect it is an issue with bracket and speech marks but the following did not work either:
SetFile -d "$(GetFileInfo -d /Users/myfilename.mov +2180 days)" /Users/myfilename.mov
How exactly should I be incorporating the '+2180 days' into it?
Edi: Mark Setchell has a solution which works but I am keen to know if there is in fact a way to incorporate '+2180 days' into the GetFileInfo-based -d date variable.
That's a lot of fun for something apparently so simple!!!! I think this works, but test it out on some sample files. I left my debugging statements in, but you can safely remove all the echo statements.
#!/bin/bash
# Get name of file as supplied as parameter
file=$1
# Get its timestamp in format "02/08/2015 21:14:44"
timestamp=$(GetFileInfo -d "$1")
echo timestamp:$timestamp
# Convert that to seconds since the Unix Epoch, e.g. 1423430084
epoch=$(date -j -f "%m/%d/%Y %H:%M:%S" "$timestamp" +%s)
echo epoch:$epoch
# Calculate seconds in 2180 days
((offset=2180*3600*24))
echo offset:$offset
# Add offset to epoch
((epoch+=offset))
echo new epoch:$epoch
# Get new date in format that SetFile wants
newdate=$(date -r $epoch "+%m/%d/%Y %H:%M:%S")
echo new date:$newdate
# And finally set the date of the input file
SetFile -d "$newdate" "$file"
Save it as ReDate and make it executable (only necessary once) with
chmod +x ReDate
and run it like this:
./ReDate /Users/myfilename.mov
Sample run:
./ReDate "/Users/Mark/tmp/file with sapce in name.mov"
timestamp:02/09/2015 09:54:01
epoch:1423475641
offset:188352000
new epoch:1611827641
new date:01/28/2021 09:54:01
I know this is an older thread, but I wanted to do something like this. The OP #MrDave is asking about adding via normal speech. This can be accomplished with AppleScript.
A bit verbose, but it works:
on run {input}
set filename to input as text
set fileDate to (creation date of (get info for input))
set newDate to fileDate + (1 * days)
set newMonth to month of newDate as number
set newMonth to lessThanTen(newMonth)
set newDay to day of newDate as number
set newDay to lessThanTen(newDay)
set newYear to year of newDate as number
set newHour to hours of newDate as number
set newHour to lessThanTen(newHour)
set newMinute to minutes of newDate as number
set newMinute to lessThanTen(newMinute)
set divider to "/"
set newSetDate to newMonth & divider & newDay & divider & newYear & " " & newHour & ":" & newMinute as text
set printNewDate to "\"" & newSetDate & "\"" as string
log printNewDate
-- date format for SetFile: mm/dd/yyyy hh:mm
do shell script ("SetFile -d " & printNewDate & " -m " & printNewDate & " " & input)
end run
on lessThanTen(num)
set thisNum to num as number
if thisNum is less than 10 then
set newNum to "0" & thisNum
else
set newNum to thisNum
end if
return newNum as string
end lessThanTen
now from terminal run:
osascript /Users/path/to/scriptName.scpt filename
and here you can actually just drag the file from Finder onto the Terminal instead of typing the filename itself, then hit enter
Related
I want to calculate number of days between two dates in the unix shell .
I tried to do a minus calculation but it dosen’t work .
This is my script
VAR1=$1
VAR2=$2
v_date_deb=`echo ${VAR1#*=}`
v_date_fin=`echo ${VAR2#*=}`
dif = ($v_date_deb - $v_date_fin)
echo dif
if [ "$v_date_deb" = "" ]
then
echo "Il faut saisir la date debut.."
exit
fi
if [ "$v_date_fin" = "" ]
then
echo "Il faut saisir la date fin.."
exit
fi
One attempt (but shot in the dark, since we don't know what is in your VAR1 variables)
ts1=$(date -d "${VAR1#*=}" +"%s")
ts2=$(date -d "${VAR2#*=}" +"%s")
dt=$(( (ts2 - ts1) / 86400 ))
Note the remark from William Pursell above: this solution is dependent on your "date" version. Date is not a built-in command from bash. And, particularly, the -d option (that allows to use the date specified instead of the current date that date is supposed to use otherwise, when used in "print the date" mode) is not common to all "date".
We have backup foldernames like "db_YYYY-MM-DD".
Is there some kind of command/expression I could use to compare the folder's (name-)date to the current (system-)date and delete anything older than X days?
Background:
We already tried "find" and "-mtime +X" but modification time is not a perfect solution because it updates when you modify/delete files inside the folders afterwards..
It is a rare condition but makes the -mtime comparison "faulty", so I look for an alternative and the folder's name doesn't change ever during creation/backup/modification..
You can use following way to generate the folder name
#foldername="db_"`date "+%Y-%m-%d"`
#echo $foldername
db_2017-08-15
#mkdir $foldername
Now you can compare like string with given date
so 7 days older date will be
givenDate="db_"`date -v-7d "+%Y-%m-%d"`
if ($foldername > $givenDate)
True if foldername sorts after givenDate lexicographically.
The good thing about the YYYY-MM-DD date format is that the dictionary comparison order matches the time order. Therefore you can simply extract the backup date from your directory name and compare it as a string with the corresponding date in the same format:
backupdirname=db_2017-08-12
X=6
backupdate="${backupdirname: -10}"
dropdate="$(date -d "$X days ago" +%Y-%m-%d)"
if [[ "$backupdate" < "$dropdate" ]]
then
echo "Delete $backupdirname"
else
echo "Keep $backupdirname"
fi
ref_date=$(date -d '2017-01-02' +%s)
for file in ./db_*; do
file_time=$(date -d ${file#*db_} +%s)
if [[ $file_time > $ref_date ]]; then
echo "$file date is newer than ref date"
# ...
else
echo "$file date is older or euqal to ref date"
# ...
fi
done
I have been working on this on and off for the last two months, and despite how many times I look at it, I can't make it work.
This script checks daily log files for a user defined variable, so they don't have to look through every one manually. It worked great checking the current month, but if the user wants to check back 20 days, and today is the 12th of this month, I wanted to be able to then go back to the previous month (not look for the log file with a date of 20150399 and so on). I have checked the logic for my date/day computations, and they seem okay (if there is a better way to do that in BASH, I am open to suggestions). What happens when I try to debug is unexpected end of file. I am somewhat new to writing scripts that contain more than 20 or so lines, but I just can't come up with what I am missing.
I have tried various fixes, to no avail, but I think this is the last iteration.
Ideas?
#!/bin/bash
########################################################
# multi_log_chk.sh
# This script will take input from the user and report which
# CyberFusion MFT logs contain what the user is looking for.
# Hopefully this will save the user having to search through every
# stinking log file to find what they are looking for.
# 20150406 pxg007 started typing
# 20150413 pxg007 added && comparison for back out (line 28)
# added message for no entries found (line 32, 38, 48-52)
# Added some further description (line 16)
# 20150424 pxg007 Added logic to calculate previous month and if necessary, year. (Lines 16-24, 60-78 )
#
########################################################
currDate=`date +%d%B%C%y`
currDay=`date +%d`
currMnth=`date +%m`
currYear=`date +%C%y`
case $currMnth in #Let's establish number of days for previous month
05 | 07 | 10 | 12 ) lastMnthD=30;;
01 |02 | 04 | 06 | 09 | 08 | 11 ) lastMnthD=31;;
03 ) lastMnthD=28;; ##and screw leap year
esac
if [ $currMnth -eq 01 ]; then ##accounting for January
lastMnth=12
else
lastMnth=$((currMnth-1))
fi
if [ $lastMnth -eq 12 ]; then ## accounting for Dec of previous year
lastMnthYr=$((currYear-1))
else
lastMnthYr=$currYear
fi
echo "This script will find entries for your query in whatever available MFT logs you request."
echo " "
echo "For instance - how many log files have transfer entries with \"DOG\" in them?"
echo " "
echo "I also will also give an estimate of how many transfers per log file contain your query, give or take a couple."
echo " "
echo "This search is case sensitive, so \"DOG\" is *** NOT *** the same as \"dog\""
echo " "
read -p "What text you are looking for? Punctuation is okay, but no spaces please. " looking ### what we want to find
echo " "
echo "Today's date is: $currDate."
echo " "
read -p "How many days back do you want to search(up to 25)? " daysBack ### How far back we are going to look
if [ "$daysBack" == 0 ] && [ "$daysBack" >> 25 ]; then
echo "I said up to 25 days. We ain't got more than that!"
exit 1
fi
echo " "
echo "I am going to search through the last $daysBack days of log files for:\"$looking\" "
echo " "
read -p "Does this look right? Press N to quit, or any other key to continue: " affirm
if [ "$affirm" = N ] && [ "$affirm" = n ]; then ###Yes, anything other than "N" or "n" is a go
echo "Quitter!"
exit 1
else
nada=0 ### Used to test for finding anything
backDate=$((currDay-daysBack)) ### current month iterator (assuming query covers only current month)
if (("$daysBack" => "$currDay")); then ## If there are more logs requested than days in the month...
lastMnthCnt=$((daysBack-currDay)) ### how many days to check last month
lastMnthStrt=$((lastMnthD-lastMnthCnt)) ## last month start and iterator
backDate=$(currDay-(daysBack-lastMnthCnt)) # Setting the iterator if we have to go back a month
while (("$lastMnthStrt" <= "$lastMnthD" )); do
foundIt=$(grep "$looking" /CyberFusion/log/Log.txt."$lastMnthYr$lastMnth$lastMnthStrt" | parsecflog | wc -l )
howMany=$((foundIt/40+1)) ### Add one in case there are less than 40 lines in the record.
if (("$foundIt" > 0))
then
nada=$((nada+1))
echo "Log.txt.$lastMnthYr$lastMnth$lastMnthStrt contains $looking in approximately $howMany transfer records."
lastMnthStrt=$((lastMnthStrt+1))
echo " "
else
lastMnthStrt=$((lastMnthStrt+1))
fi
fi
backDate=$((currDay-daysBack)) ### current month iterator (assuming query covers only current month)
while (("$backDate" <= "$currDay")); do
foundIt=$(grep "$looking" /CyberFusion/log/Log.txt."$backDate" | parsecflog | wc -l )
howMany=$((foundIt/40+1)) ### Add one in case there are less than 40 lines in the record.
if (("$foundIt" > 0))
then
nada=$((nada+1))
echo "Log.txt.$backDate contains $looking in approximately $howMany transfer records."
backDate=$((backDate+1))
echo " "
else
backDate=$((backDate+1))
fi
if [ "$nada" \< 1 ]
then
echo " "
echo "I found no entries for $looking in any log file."
fi
You are missing the keyword 'done' on lines 81 and 96 and also a final 'fi' keyword on the last line.
Also as others suggested you can do
date -d "20 days ago" +"%d%B%C%y"
to easily get dates in the past
So I've got this script that runs on rhel 5.8 and what it does is that it reads two arguments, should be dates in yyyy-mm-dd format, and fires a script on a remote server, sunOS 5.10. In both sides the shell I'm using is /bin/bash
The part of the code that's not working as expected is the below:
...
CC="IE"
read -p "Please provide start date (format yyyy-mm-dd): " STARTDATE
read -p "Please provide end date (format yyyy-mm-dd): " ENDDATE
echo ""
echo "Start Date provided :" $STARTDATE
echo "End date provided :" $ENDDATE
echo ""
echo "Executing query on the remote side, please wait..."
ssh -t user#rem_host '/tmp/rem_script.sh '${CC}' '${STARTDATE}' '${ENDDATE}' ' >/dev/null 2>&1
What I get when set -x on the local host is the following
+ read -p 'Please provide start date (format yyyy-mm-dd): ' STARTDATE
Please provide start date (format yyyy-mm-dd): 2014-05-08
+ read -p 'Please provide end date (format yyyy-mm-dd): ' ENDDATE
Please provide end date (format yyyy-mm-dd): 2014-05-09
+ echo ''
+ echo 'Start Date provided :' 2014-05-08
Start Date provided : 2014-05-08
+ echo 'End date provided :' 2014-05-09
End date provided : 2014-05-09
+ echo ''
+ echo 'Executing query on the remote side, please wait...'
Executing query on the remote side, please wait...
+ ssh -t user#rem_host '/tmp/rem_script.sh IE 2014-05-08 2014-05-09 '
But what I see on the remote side being executed is the following:
user 730 688 0 10:30:31 pts/2 0:00 bash -c /tmp/rem_script.sh IE 2014-05-08 2014-05
Can anyone please tell me why the last date is being chopped off? How can I correct this?
Thanks in advance...
I can use
set modDate to the modification date of theFile as string to get the last modified date of a file, and
set modDate to the creation date of theFile as string to get the date when the file was created.
Is there anything like last opened date to get the date when the file was last opened?
Yes. There is a UNIX command called kMDItemLastUsedDate that returns the date the target item was last used.
set the Last_opened_date to (do shell script "mdls -name kMDItemLastUsedDate " & quoted form of the POSIX path of theFile)
However, this command doesn't return a literal date object. Instead, it returns a date object in ISO 8601:2004 format (YYYY-MM-DD HH:MM:SS) which, if you try to put date before it, you'll get a syntax error.
Here is the revised script:
property months : {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
set the Last_opened_date to date convert_date(do shell script "mdls -name kMDItemLastUsedDate " & quoted form of the POSIX path of theFile)
on convert_date(passed_data)
set prevTIDs to AppleScript's text item delimiters
set AppleScript's text item delimiters to space
set the ISO_date to the first text item of (passed_data as string)
set AppleScript's text item delimiters to "-"
set the date_parts to every text item of the ISO_date
set the_year to the first text item of the date_parts
set the_month to the second text item of the date_parts
set the_day to the third text item of the date_parts
set AppleScript's text item delimiters to space
set the time_string to the second text item of (passed_data as string)
set AppleScript's text item delimiters to prevTIDs
return item (the_month as integer) of months & the_day & ", " & the_year & space & the time_string
end convert_date
i had the problem of wanting to get a date that was only available in the spotlight metadata (image file's content created date "kMDItemContentCreationDate" - original date from camera, i think). so i came up with this; note: i used "copy" and "tell" for my own clarity/ocd. there is an "as date" coercion for "do shell script" but it just gave me different errors. there is also simpler and better "awk"'s to do more/better things but the "- name " gives just the one mdls value you ask for.
(* gets the mdls value of "metaDate" ie one of the many available metadata dates
"qpImg" is the "quoted form of posix path" of some file
the awk strips it down to just the actual date/time string *)
tell current application to copy (do shell script ("mdls " & " -name " & metaDate & " " & qpImg & " | awk -F ' ' '/Date/ {print $3,$4};'")) to targDate
(* takes mdls info dates in form "2012-01-19 14:37:38 -500" and makes it applescripty.
"inText" is a posix path that is converted to it's "quoted form" on the fly.
the "%x %r" is "standard numeric" date and 12hr time and can be coerced via "as date" *)
tell current application to set formtdDate to do shell script "date -j -f '%Y-%m-%d %H:%M:%S' " & quoted form of inText & " +'%x %r'"
-- the two can be combined using xargs
tell current application to copy (do shell script ("mdls -name " & metaDate & " " & qpImg & " | awk -F ' ' '{print $3,$4};' | xargs -0 -I indate date -j -f '%Y-%m-%d %H:%M:%S' indate +'%x %r'")) to targDate
There isn't a pure AppleScript solution to obtain a file's last access date. Using a combination of the shell tools stat and date you can construct an AppleScript helper function that provides the last opened date:
on LastOpenedDate(theFile)
set theStr to do shell script "date -r $(stat -f %a " & quoted form of (POSIX path of theFile) & ") +%Y-%m-%dT%H:%M:%S"
ISODateStrToDate(theStr)
end LastOpenedDate
The function uses the following helper function to convert the last opened time stamp which is returned as a ISO 8601 formatted string to an AppleScript date:
on ISODateStrToDate(theStr)
set dt to (current date)
set savedDelimeters to AppleScript's text item delimiters
set AppleScript's text item delimiters to {"-", "T", ":"}
set {dt's year, dt's month, dt's day, dt's hours, dt's minutes, dt's seconds} to (every text item of theStr)
set AppleScript's text item delimiters to savedDelimeters
return dt
end ISODateStrToDate
The function LastOpenedDate can be invoked with an alias, file or POSIX file as an argument, e.g.:
LastOpenedDate(POSIX file "/var/log/system.log")
returns
date "Saturday, August 27, 2011 4:04:52 PM"
on my machine.