I've got a bunch of .cr2 and .jpg files with exact same names. ".cr2" is a file format for digital negative, every .jpg is a converted to 8bit version of cr2-photo. Every photographer with canon camera get this kind of structure: take one picture - get one .cr2 version and one .jpg version. Cr2-s weights a lot, thats why I send jpegs to my clients to filter. After they send back best hundred photos from thousands, I must pick cr2 versions of this photos, one by one. There is gotta be a better way. In windows I find a way to select this files in totalcommander through copy selection to buffer - modifing(replace in text editor every ".jpg" to ".cr2") and then restore selection from buffer. This problem is seemed dumn, but I can't find an answer to mac, it took forever to select this files one by one and all photographers I know doing the same, which is driving me crazy.
Here is a bash script that should do what you want simply by double-clicking it. First you need to edit the first 2 lines to tell it 1) where the CR2 files can be found and 2) where the JPEGs are that the client has accepted.
Initially, I am assuming the CR2 files are somewhere under your login/home directory and that the JPEGs accepted by the client are on your Desktop in a folder called accepted. Edit lines 3 and 4 to reflect the actual situation, then save the following script on your Desktop as GetCR2s.command.
#!/bin/bash
#
# You can edit the next two lines to match your setup
CR2LOCATION="$HOME"
ACCEPTEDLOC="$HOME/Desktop/accepted"
shopt -s nocasematch # Match JPG and jpg and CR2 and cr2 regardless of case
shopt -s nullglob # Don't die if there are no files
# Tell user what is going on...
echo Locating CR2s in $CR2LOCATION, to match accepted files in $ACCEPTEDLOC...
# Go where the JPEGs are, or give up
cd "$ACCEPTEDLOC" 2> /dev/null
if [ $? -ne 0 ]; then echo ERROR: Unable to change directory to $ACCEPTEDLOC; exit 1; fi
# Consider all JPEGs in this directory
for f in *.jpg; do
cr2="${f%%jpg}cr2" # Replace "jpg" extension with "cr2"
echo Processing \"$f\", looking for \"$cr2\"...
find "$CR2LOCATION" -iname "$cr2" -not -path "$ACCEPTEDLOC" -exec cp "{}" . \; 2> /dev/null
done
Then, start the Terminal application, and do the following just one time before use in order to make the script executable:
cd Desktop
chmod +x GetCR2s.command
Now you should be able to save the images your client has accepted (by clicking Save Attachments in your Email program) into the Desktop/accepted folder, then simply double-click on the script GetCR2s.command on your Desktop and it will gather all the matching CR2 files into that folder for you.
Related
I'm using Mac Automator to run a shell script to execute a SoX command, and I'll ultimately save that workflow as a Service called "Combine". I'm virtually a complete beginner but I do at least know within Automator to set Shell: bin/bash and Pass inputs: as arguments.
I'm trying to be able to select multiple .wav files in the SAME folder using FINDER (though not necessarily ALL files in that folder, just the ones I have specifically selected), and have Automator instruct SoX to simply combine/concatenate those selected audio files sequentially into one output file called combined.wav. For example if I selected two audio files within a folder that were 2 minutes each, I'd end up with a 4 minute "combined.wav" file.
I have the script below as a starting point to use within Automator, but the problem with this language is, instead of actually combining multiple files I have selected within a folder, it just passes the last file through with the combined.wav name but nothing gets combined. Pretty sure the problem lies in the sox command itself, probably the "$f" is the mistake if I had to guess.
#!/bin/bash
for f in "$#"; do
combinedFolder="$(dirname "$f")/Combined"
fileName=$(basename "$f")
if [ ! -d "${combinedFolder}" ]; then
mkdir "${combinedFolder}"
fi
/Applications/SoX/sox "$f" "${combinedFolder}/combined.wav"
done
Ideally I'd love to have two versions of this (corrected) script... one putting the combined.wav output file in a "Combined" subfolder as the text above suggests, but also would love to have an alternate (simpler) script that simply puts the combined.wav in the same folder as the individual input files I've selected, with no subfolder.
I would like to do some file name comparison with the bash script to determine the file should run a compress routine or not.
Here what I want to do, look through the UPLOAD folder and all sub-folders (couple hundreds of folders in total), if filenameA.jpg and filenameA.orig are both exist in the same folder that means it is compressed before and no need to compress it again, otherwise will compress the filenameA.jpg file.
This way only compress the newer added file and not file already compressed before.
Can someone tell me how to do the if / loop statement using bash script? I plan to run it by Cron job.
Thank you for your help.
Use find to recursively search for all files named *.jpg.
For each file returned you would check for a corresponding ".orig" file, and based on the result compress of not.
Something like this perhaps should get you started:
find UPLOAD -type f -name '*.jpg' | while read JPG
do
ORIG="${JPG%.jpg}.orig"
if [ -s ${ORIG} ]
then
echo "File ${JPG} already compressed to ${ORIG}"
else
echo "File ${JPG} need compressing ..."
gzip -c ${JPG} > ${ORIG}
fi
done
I am using preview (that comes with OS X El Capitan) feature to convert a file form TIFF format into JPG for example. I expected the export process will include the original comments, but it doesn't happen (it applies also for the tag fields).
The generated JPG file has no comment
The compression and change image format work, but the META INFO such as comment or tags are not exported.
Any suggestion or workaround about how to include that information. I need to convert about 500 images so manually copy/paste doesn't work for me.
Updated Answer
In the light of your comments, I think the best way forward is to try and identify how/where the comments are stored for each platform (Windows vs macOS) and then to decide which method you want to use going forward.
macOS Finder/Spotlight comments will not be legible on Windows, so if you want Windows compatibility, you need to standardise on JPEG or EXIF comments.
I recommend using exiftool which you can install with homebrew, using:
brew install exiftool
Then I suggest you try extracting the comments from your files to see how/where they are stored:
exiftool -a image.jpg
will show you all tags in image.jpg. Your comments may be under:
comment - which is the JPEG comment, or
EXIF:UserComment - which is the EXIF comment
If you find your comments in the JPEG or the EXIF section, you can extract just the comments with:
exiftool -comment image.jpg # extract JPEG comment
exiftool -EXIF:UserComment image.jpg # extract EXIF UserComment
Add the option -s3 to suppress the field-names in the above to save having to parse them out.
Likewise, you can set the comments with:
exiftool -comment="FUNKY JPEG COMMENT" image.jpg # set JPEG comment
exiftool -EXIF:UserComment="FUNKY EXIF USER COMMENT" image.jpg # set EXIF UserComment
You can also extract the EXIF user comments to a CSV with:
exiftool -EXIF:UserComment -csv *.jpg
SourceFile,UserComment
a.jpg,FUNKY EXIF:UserComment
b.jpg,b FUNKY EXIF:UserComment
You can also apply comments from a CSV.
You should also be able to extract macOS/Spotlight/Finder comments using the script in my main answer:
$HOME/macOSGetFinderComment "/Users/someone/soneFile.tif"
Original Answer
I would suggest you try the following using ImageMagick.
First, use the Finder, or any other tool you are familiar with, to make a copy of your photos including the entire directory structure to some new place where we cannot damage your existing photos. So, let's say you copy (NOT move) the entire tree of TIFs to a subdirectory called "NEW" inside your HOME directory.
Then start the Terminal and change directory to "NEW":
cd NEW
Easy Method
If all the TIFs are in a single directory or two, just use mogrify:
mogrify -format jpg *.tif
Harder Method
If the TIF files are in multiple directories, you will need to work a bit harder. Inside Terminal copy and paste this:
find NEW -name \*.tif -exec sh -c 'new="${1%.tif}.jpg"; convert "{}" "$new"' _ {} \;
That starts looking in the "NEW" directory for files named "*.tif". When it finds one, it starts a new shell (sh) passing it the filename of the TIF. It then works out the new filename by replacing a trailing "tif" with "jpg" and invokes ImageMagick convert to do the conversion.
As regards the Finder/Spotlight comments, here is a little script to get the Finder comment of a file:
#!/bin/bash
# macOSGetFinderComment
# Pass an absolute path to the file!
file=$1
osascript<<EOF
tell application "Finder" to get comment of item POSIX file "$file"
EOF
And here is one to set the Finder/Spotlight comment:
#!/bin/bash
# macOSSetFinderComment
# Pass an absolute path to the file!
file=$1
comm=$2
osascript<<EOF
tell application "Finder" to set comment of item POSIX file "$file" to "$comm"
EOF
So, I would save those 2 scripts in your HOME directory and then make them executable with:
cd
chmod +x macOS*FinderComment
Then save this file in your HOME directory under $HOME/CopyComments:
#!/bin/bash
shopt -s nullglob
for f in $(pwd)/*.tif; do
comment=$($HOME/macOSGetFinderComment "$f")
new="${f%.tif}.jpg"
echo Setting comment of $new to $comment
$HOME/macOSSetFinderComment "$new" "$comment"
done
and make it executable with:
chmod +x $HOME/CopyComments
and run it with:
cd NEW
$HOME/CopyComments
I have posted this problem also in Apple Community, here is the solution proposed by VikingOSX. It is a big piece of code, so better download it from here or directly from the Apple Community Link mentioned. Here is a description about the solution as described in the original post:
Prompts for a source folder, and a destination folder.
Duplicates folder hierarchy from source to destination folder.
Selects all TIFF images in the folder hierarchy and converts them to JPEG.
For sub-folders and their files, transfers the original Finder comments, color tags and tag name(s) to the destination hierarchy.
The compression level for the JPG file is high, it can be modified for: medium or low in the line: save this_img as JPEG in outfile_name with compression level medium with icon
Limitation: Source folder can only contain one-level of sub-folders. Ignoring this will result in unplanned results.
Additional Comments
Uses a with timeout clause to allow for large number of files. AppleScript does not yet support Finder tag names, so this script uses AppleScript/Objective-C to get and set those tag name(s). Due to this extension, the script now requires AppleScript 2.4 and must be run on OS 10.10 or later.
Due to the AppleScript/Objective-C code, the script cannot be run interactively as a script/script bundle without using the control+command+R keyboard shortcut. A test is made when the script starts, and will warn appropriately. It is best to save the script as an application to avoid this keyboard shortcut altogether.
Usage
Save the script and then copy and paste the file contains into the Script Editor (you can find the application in the folder: Utilities under the name: Script Editor), compile and save the file with the format: Application, then double click on it to run the script application.
I have tested the script under with Mac Air 2010, with OS El Capitan, for a folder with 884 TIFF files with 2.25GB size and it takes about 18 minutes to convert them into JPG files with medium compression level. The generated files will contain the tags and comments from the original equivalent TIFF file.
Disclaimer
Comment and tags generated in one platform for example Windows or mac OS are not visualized in the other platform. Tags created in Windows are treated in mac OS as keywords (Comand+i for visualizing them), but comments generated in Windows are not visualized in mac OS. This is general incompatibility problem that apply for photos in any format (for example TIFF or JPG).
EDIT (updated solution for solving cross-platform problem with comments)
Taking the idea from #MarkSetchell, I adapted the original script to at least solve the cross-platform problem from macOS to Windows, i.e. a comment from macOS can be seen in Windows platform. The idea is to use EXIF metadata. Then the Applescript will invoke the shell script for invoking the exiftool:
set uxFilepath to POSIX path of NewIMG
do shell script "/usr/local/bin/exiftool -overwrite_original -EXIF:UserComment=\"" & cmtstr & "\" " & uxFilepath
Windows processes the UserComment metadata from EXIF as a regular file comment. Now same comment on the TIF file will be on the JPG and also because such comments were copied (copy-paste) into an EXIF metadata the same information will be visualized under Windows. The same idea can be used for other file properties, in case Windows/Mac read it.
The EXIF metadata in macOS can be visualized from command line as suggest #MarkSetchell, but also from Finder: Command+o (to launch preview app), then Command+i (to launch the inspector). Then click on tap: "More Info", then the tab EXIF.
For the opposite process will require an script that does the opposite, i.e., copy EXIF comment using exiftool, into macOS comment. I have verified that in such case the Windows comment will appear under the label: XPComment. The script uses: UserComment, but it works using XPComment as label in both directions.
I have a lot of files named the same, with a directory structure (simplified) like this:
../foo1/bar1/dir/file_1.ps
../foo1/bar2/dir/file_1.ps
../foo2/bar1/dir/file_1.ps
.... and many more
As it is extremely inefficient to view all of those ps files by going to the
respective directory, I'd like to copy all of them into another directory, but include
the name of the first two directories (which are those relevant to my purpose) in the
file name.
I have previously tried like this, but I cannot get which file is from where, as they
are all named consecutively:
#!/bin/bash -xv
cp -v --backup=numbered {} */*/dir/file* ../plots/;
Where ../plots is the folder where I copy them. However, they are now of the form file.ps.~x~ (x is a number) so I get rid of the ".ps.~*~" and leave only the ps extension with:
rename 's/\.ps.~*~//g' *;
rename 's/\~/.ps/g' *;
Then, as the ps files have hundreds of points sometimes and take a long time to open, I just transform them into jpg.
for file in * ; do convert -density 150 -quality 70 "$file" "${file/.ps/}".jpg; done;
This is not really a working bash script as I have to change the directory manually.
I guess the best way to do it is to copy the files form the beginning with the names
of the first two directories incorporated in the copied filename.
How can I do this last thing?
If you just have two levels of directories, you can use
for file in */*/*.ps
do
ln "$file" "${file//\//_}"
done
This goes over each ps file, and hard links them to the current directory with the /s replaced by _. Use cp instead of ln if you intend to edit the files but don't want to update the originals.
For arbitrary directory levels, you can use the bash specific
shopt -s globstar
for file in **/*.ps
do
ln "$file" "${file//\//_}"
done
But are you sure you need to copy them all to one directory? You might be able to open them all with yourreader */*/*.ps, which depending on your reader may let browse through them one by one while still seeing the full path.
You should run a find command and print the names first like
find . -name "file_1.ps" -print
Then iterate over each of them and do a string replacement of / to '-' or any other character like
${filename/\//-}
The general syntax is ${string/substring/replacement}. Then you can copy it to the required directory. The complete script can be written as follows. Haven't tested it (not on linux at the moment), so you might need to tweak the code if you get any syntax error ;)
for filename in `find . -name "file_1.ps" -print`
do
newFileName=${filename/\//-}
cp $filename YourNewDirectory/$newFileName
done
You will need to place the script in the same root directory or change the find command to look for the particular directory if you are placing the above script in some other directory.
References
string manipulation in bash
find man page
First bash script and I'm running into some issues. I want to take a screenshot, then change the name of the .png to a random number (so that pictures don't overwrite). After it's renamed I want to move the picture to my dropbox folder.
This is what I've got:
#!/bin/bash
#Take screenshot
import -window root $HOME/screenshot.png
#Move to dropbox folder
mv $HOME/screenshot.png $HOME/Dropbox/Max-Max/$RANDOM.png
When I run it dropbox is getting some kind of something because my taskbar icon indicates a file transfer. When I open up the folder however, nothing's there.
Thanks for the help.
Instead of $RANDOM use $(date|tr " :" _)
Much more useful
You can do that with scrot like this:
scrot -e 'mv $f ~/Dropbox/Max-Max'
But your script looks fine... Try to create an empty file first to make sure your dropbox functions fine.
echo > ~/Dropbox/Max-Max/testfile
The commands you're using are correct. The only way it could fail is if Max-Max doesn't exist. mv moves and renames files among existing directories -- mv cannot create directories.