Bash script for taking a screenshot, renaming and moving - bash

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.

Related

Copy file without file extension to new folder and rename it

I just during the weekend decided to try out zsh and have a bit of fun with it. Unfortunately I'm an incredible newbie to shell scripting in general.
I have this folder with a file, which filename is a hash (4667e85581f80b6936f8811f0a7493c70eae4ee7) without a file-extension.
What I would like to do is copy this file to another folder and rename it to "screensaver.png".
I've tried with the following code:
#!/usr/bin/zsh
KUVVA_CACHE="$HOME/Library/Containers/com.kuvva.Kuvva-Wallpapers/Data/Library/Application Support/Kuvva"
DEST_FOLDER="/Library/Desktop Pictures/Kuvva/$USERNAME/screensaver.png"
for wallpaper in ${KUVVA_CACHE}; do
cp -f ${wallpaper} ${DEST_FOLDER}
done
This returns the following error:
cp: /Users/Morten/Library/Containers/com.kuvva.Kuvva-Wallpapers/Data/Library/Application Support/Kuvva is a directory (not copied).
And when I try to echo the $wallpaper variable instead of doing "cp" then it just echo's the folder path.
The name of the file changes every 6 hour, which is why I'm doing the for-loop. So I never know what the name of the file will be, but I know that there's always only ONE file in the folder.
Any ideas how I can manage to do this? :)
Thanks a lot!
Morten
It should work with regular filename expansion (globbing).
KUVVA_CACHE="$HOME/Library/Containers/com.kuvva.Kuvva-Wallpapers/Data/Library/Application Support/Kuvva/"
And then copy
cp -f ${KUVVA_CACHE}/* ${DEST_FOLDER}
You can add the script to your crontab so it will be run at a certain interval. Edit it using 'crontab -e' and add
30 */3 * * * /location/of/your/script
This will run it every third hour. First digit is minutes. Star indicates any. Exit the editor by pressing the escape-key, then shift+: and type wq and press enter. These vi-commands.
Don't forget to 'chmod 0755 file-name' the script so it becomes executable.
Here is the script.
#!/bin/zsh
KUVVA_CACHE="$HOME/Library/Containers/com.kuvva.Kuvva-Wallpapers/Data/Library/Application Support/Kuvva"
DEST_FOLDER="/Library/Desktop Pictures/Kuvva/$USERNAME/screensaver.png"
cp "${KUVVA_CACHE}/"* "${DEST_FOLDER}"

OS X bash For loop only processes one file in a directory

I'm trying to get this code to process all files in a directory : https://github.com/kieranjol/ifi-ffv1/blob/master/ifi-ffv1.sh
I run it in the terminal and add path to file ./ifi-ffv1.sh /path/to/file.mov. How can I get it to move on to the next? I'll also need to make sure that it only processes AV files, such as .avi/.mkv/*.mov etc.
I've tried using while loops with shift but I can't get that to work either.
I've tried adding a specific path like here but I'm failing http://www.cyberciti.biz/faq/unix-loop-through-files-in-a-directory/
I've tried this https://askubuntu.com/a/315338 and it keeps looping the same file rather than moving on to the next one. http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-7.html this didn't help me either.
I know this is going to be a horribly simple solution but I'm very new to this.
You don't actually have any kind of loop in your code. You need to do something like
for file in path/to/*.avi path/to/*.avg
do
./ifi-ffv1.sh "$file"
done
which will loop through all the specified files and substitute each one for $1
You can put whatever file names you want instead of the path/to/*.avi path/to/*.avg. If you cd to the directory first, you can leave out the paths, and just use *.avi *.avg
To do it all in one script, do something like this:
cd <your directory>
for file in *.avi *.avg
do
<your existing script here>
done
replacing all the $1's in your script with "$file" (not duplicating any quotes you already have, of course)

How to create a batch file in Mac?

I need to find a solution at work to backup specific folders daily, hopefully to a RAR or ZIP file.
If it was on PC, I would have done it already. But I don't have any idea to how to approach it on a Mac.
What I basically want to achieve is an automated task, that can be run with an executable, that does:
compress a specific directory (/Volumes/Audio/Shoko) to a rar or zip file.
(in the zip file exclude all *.wav files in all sub Directories and a directory names "Videos").
move It to a network share (/Volumes/Post Shared/Backup From Sound).
(or compress directly to this folder).
automate the file name of the Zip file with dynamic date and time (so no duplicate file names).
Shutdown Mac when finished.
I want to say again, I don't usually use Mac, so things like what kind of file to open for the script, and stuff like that is not trivial for me, yet.
I have tried to put Mark's bash lines (from the first answer, below) in a txt file and executed it, but it had errors and didn't work.
I also tried to use Automator, but it's too plain, no advanced options.
How can I accomplish this?
I would love a working example :)
Thank You,
Dave
You can just make a bash script that does the backup and then you can either double-click it or run it on a schedule. I don't know your paths and/or tools of choice, but some thing along these lines:
#!/bin/bash
FILENAME=`date +"/Volumes/path/to/network/share/Backup/%Y-%m-%d.tgz"`
cd /directory/to/backup || exit 1
tar -cvz "$FILENAME" .
You can save that on your Desktop as backup and then go in Terminal and type:
chmod +x ~/Desktop/backup
to make it executable. Then you can just double click on it - obviously after changing the paths to reflect what you want to backup and where to.
Also, you may prefer to use some other tools - such as rsync but the method is the same.

Copying multiple files with same name in the same folder terminal script

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

Finding files with bash and copy to another location and reducing depth of folders

I'm trying to recover a mates hard drive, there is no structure what so ever so music and images are everywhere but in named folders sometimes >5 folders deep, I've managed to write a one-liner that finds the files and copies them to a mounted drive but it preserves the file structure completely. What I'm after is a bit of code that searches the drive and copies to another location and copies just the parent folder with the mp3/jpg files within and not the complete path. The other issue I have is the music is /folder/folder/folder/Artist/1.mp3..2.mp3..10.mp3 etc etc so I have to preserve the folder 'Artist' to give him any hope of finding his tracks again.
What I have working currently:
find /media/HP/ -name *.mp3 -fprintf /media/HP/MUSIC/Script.sh 'mkdir -p "/media/HP/MUSIC/%h" \n cp "%h/%f" "/media/HP/MUSIC/%h/"\n'
I then run the script.sh and it does all the copying.
Many Thanks
What you probably want to do will be along the lines of:
mkdir "$dest/$(basename $(dirname $source))"
OK folks - thanks for the input it did make me think deeper about this and I've come up with a result with the help of a colleague (thanks SiG):
This one-liner finds the files, and writes a script file to run separately but does copy across just the last folder as I wanted initially.
The Code:
find /some/folder/ -name *.mp3 | awk 'BEGIN{FS="/"}{print "mkdir -p \"/some/new/place/" $(NF-1) "\"\ncp -v -p \"" $0 "\" \"/some/new/place/" $(NF-1) "/" $NF "\""}' > script.sh
The output is:
mkdir -p "/media/HP/MUSIC/Satize" cp -v -p "/media/HP/Users/REBEKAH/Music/Satize/You Don't Love Me.mp3" "/media/HP/MUSIC/Satize/You Don't Love Me.mp3"
When script.sh is run it does all the work and I end up with a very reduced file structure I can copy to a new drive.
Thanks again folks much appreciated.
KjF
If you are doing the operation recursively ( entering directory by directory ), what you can do is everytime save your path as: Road_Dir=$(pwd)(let's say dir1/dir2/dir3/)
Then you detect your artist_name directory you save it is Music_Dir=$(pwd)
Finally you could extract your artist_name directory with the simple command:
Final_Dir=${Music_Dir##$Road_Dir/} (wich means take out the string $Road_Dir/ from $Music_Dir beginning from the left of $Music_Dir)
With this Final_Dir will contain artist_name, and you can copy your music file as $Final_Dir/Music.mp3 ...

Resources