Get file size in Automator workflow - bash

Creating a service in Automator (Run shell script > Bash) to copy to clipboard filesize (in bytes) of selected file in Finder. I'm not very well versed in bash, and can't see where this is wrong.
Aim is to have it appear in the 'services' menu when right clicking a file, and then I can just paste the filesize wherever I fancy.
Options I have selected in Automator are:
Service receives selected "files or folders" in "Finder.app"
Shell /bin/bash
Pass input as arguments
for f in "$#"
do
getty=$(ls -l "$f")
done
IFS=' ' read -a newList <<< "${getty}"
echo -n ${newList[4]} | pbcopy
Run Shell Script failed - 1 error:
-: -c: line1: syntax error near unexpected token `do

Instead of using ls, use stat to get the file size.
stat -f '%z' "$f" | pbcopy
To copy, say, the name and size of a group of files to the clipboard:
stat -f '%N %z' "$#" | pbcopy

To make it clearer to everyone, the solution is :
create an empty automator script
add action "get selected elements from Finder
add action "Run shell script" with inputs as arguments
with the following script :
stat -f '%z' "$#" | pbcopy

Related

Checking file existence in Bash using commandline argument

How do you use a command line argument as a file path and check for file existence in Bash?
I have the simple Bash script test.sh:
#!/bin/bash
set -e
echo "arg1=$1"
if [ ! -f "$1" ]
then
echo "File $1 does not exist."
exit 1
fi
echo "File exists!"
and in the same directory, I have a data folder containing stuff.txt.
If I run ./test.sh data/stuff.txt I see the expected output:
arg1=data/stuff.txt
"File exists!"
However, if I call this script from a second script test2.sh, in the same directory, like:
#!/bin/bash
fn="data/stuff.txt"
./test.sh $fn
I get the mangled output:
arg1=data/stuff.txt
does not exist
Why does the call work when I run it manually from a terminal, but not when I run it through another Bash script, even though both are receiving the same file path? What am I doing wrong?
Edit: The filename does not have spaces. Both scripts are executable. I'm running this on Ubuntu 18.04.
The filename was getting an extra whitespace character added to it as a result of how I was retrieving it in my second script. I didn't note this in my question, but I was retrieving the filename from folder list over SSH, like:
fn=$(ssh -t "cd /project/; ls -t data | head -n1" | head -n1)
Essentially, I wanted to get the filename of the most recent file in a directory on a remote server. Apparently, head includes the trailing newline character. I fixed it by changing it to:
fn=$(ssh -t "cd /project/; ls -t data | head -n1" | head -n1 | tr -d '\n' | tr -d '\r')
Thanks to #bigdataolddriver for hinting at the problem likely being an extra character.

Why is this bash script not changing path?

I wrote a basic script which changes the directory to a specific path and shows the list of folders, but my script shows the list of files of the current folder where my script lies instead of which I specify in script.
Here is my script:
#!/bin/bash
v1="$(ls -l | awk '/^-/{ print $NF }' | rev | cut -d "_" -f2 | rev)"
v2=/home/PS212-28695/logs/
cd $v2 && echo $v1
Does any one knows what I am doing wrong?
Your current script makes no sense really. v1 variable is NOT a command to execute as you expect, but due to $() syntax it is in fact output of ls -t at the moment of assignment and that's why you have files from current directory there as this is your working directory at that particular moment. So you should rather be doing ordinary
ls -t /home/PS212-28695/logs/
EDIT
it runs but what if i need to store the ls -t output to variable
Then this is same syntax you already had, but with proper arguments:
v1=$(ls -t /home/PS212-28695/logs/)
echo ${v1}
If for any reason you want to cd then you have to do that prior setting v1 for the same reason I explained above.

Create log history excluding some command in bash MacOSX

impossible to find an answer to that:
i would like to create a log history of my command line automatically without having to do anything.
For that i found some clues, i modified my .bash_profile
but i need to exclude some command that i don't want in my log like "ls, cd, etc."
this doesn't work, and i can't d
so here's my code:
# log every command typed and when
command_out=( "more" "less" "cd" "open" "ls" "pwd" "nano" "man" "help") #array of command i don't want to save in my log
my_TEST=0 ##setup a var
FIRST_COMMAND=$(echo $BASH_COMMAND| cut -d' ' -f 1) ##get only the first command
## test if the first command is in the array
for elm in "${command_out[#]}"; do
if [[ $FIRST_COMMAND == $elm ]]; then
echo $elm # does not work
$my_TEST=1 ## if the command is in the array the var is setup to 1
fi
done
if [[ $my_TEST == 0 ]] && [ -n "${BASH_VERSION}" ]; then
trap "caller >/dev/null || \
printf '%s\\n' \"\$(date '+%Y-%m-%dT%H:%M:%S%z')\
\$(tty) \${BASH_COMMAND}\" 2>/dev/null >>~/.command_log" DEBUG
fi
if you any other ideas of how to do what i want i'm open
Thanks you
Bash automatically keeps a history of every command you type; you can use the history command to view it. If you want to exclude certain commands, rather than trying to exclude them from the log, I would skip them when viewing it, e.g. history | egrep -vw 'ls|cd|other|commands|here'.
You can set HISTTIMEFORMAT to get a timestamp with every entry, control how many commands are kept with HISTFILESIZE, and if you really want to keep some commands out instead of just not seeing them when you look, you can list them in HISTIGNORE. See https://www.gnu.org/software/bash/manual/html_node/Using-History-Interactively.html.
Your ~/.bash_history file should already contain your complete command history. You could use something like
cat ~/.bash_history | grep -v cd | egrep -v 'cd|ls|...'
to filter out the commands you're not interested in.
So for the list you specified:
cat ~/.bash_history | egrep -v 'more|less|cd|open|ls|pwd|nano|man|help'
I completed Mark Reed answer with what i precisely wanted. Here is my code:
# changes the .bash_history file mode to append
shopt -s histappend
#configures the history -a command to be run at each shell prompt. The -a immediately writes the current/new lines to the history file.
PROMPT_COMMAND="history -a;$PROMPT_COMMAND"
#list of command i don't want in my history
HISTIGNORE='ls*:exit:pwd:clear:cd*:man*:more*:less*:head*:tail*:nano*:open*:help*'
#set no limit to the history file size
HISTSIZE= HISTFILESIZE=

Use "Touch -r" for several files with automator

I use "MacOS X Yosemite (10.10.4)"
I've converted video mts files to mov files using QuickTime, but the new file created doesn't preserve original Creation Date.
fileA.mts --> Creation Date: 07/02/2010 10:51
fileA_converted.mov --> Creation Date: Today 8:35
I'd like to change the Creation Date attribute of several files, using the date of the original files. I know I can do this by using Terminal "Touch" command in order to this:
touch -r fileA.mts fileA_converted.mov
touch -r fileB.mts fileB_converted.mov
As I have more than 200 files to change Creation Date, is it possible to automate this using automator Script Shell action, or any other way?
Like this in the bash shell - which is what you get in Terminal (untested):
#!/bin/bash
for orig in *.mts; do
# Generate new name from old one
new="${orig/.mts/_converted.mov}"
echo touch -r "$orig" "$new"
done
Save the above in a file called doDates and then type this in the Terminal
chmod +x doDates # make the script executable
./doDates # run the script
Sample output
touch -r Freddy Frog.mts Freddy Frog_converted.mov
touch -r fileA.mts fileA_converted.mov
At the moment it does nothing, but run it, see if you like what it says, and then remove the word echo and run it again if all looks ok.
Execute below command when we have all original and converted files in same folder
ls | grep ".mts" | awk -F. '{print $0" "$1"_converted.mov"}' | xargs touch -r
when we have different folder run below command on path where .mts files are present and add absolute path before $1 just like I have added /home/convertedfiles/
ls | grep ".mts" | awk -F. '{print $0" /home/convertedfiles/"$1"_converted.mov"}' | xargs touch -r

bash osx open file via variable or pipe

I would like to open a file using the osx open command, but all I have is a variable containing the filename (and path) instead of the filename itself.
I tried:
thisfile=./filename.extension
open $thisfile
and
thisfile=./filename.extension
printf $thisfile | open
and
printf ./filename.extension | open
but in all of these attempts I just get
Usage: open [-e] [-t] [-f] [-W] [-R] [-n] [-g] [-h] [-b <bundle identifier>] [-a <application>] [filenames] [--args arguments]
Help: Open opens files from a shell.
... (full text: http://pastie.org/10074666)
What am I doing wrong? How can I open the file through a pipe and with a variable?
EDIT/solution:
I did have spaces (and parentheses) which I escaped with \ before storing in the variable. It turns out I should not have done that and I should have used open "${thisfile}" not open $thisfile
so for file
./foo - moo/zoo - boo (100)/poo (too).jpg
open with open via variable like this
thisfile='./foo - moo/zoo - boo (100)/poo (too).jpg'
open "${thisfile}"
As #mark-setchell commented about it, open does not take anything on stdin. So let's understand what would be wrong with the first scenario.
when you try to open a file using the open command on OSX, I see three main scenarios:
① the file does not exist or has spaces:
% open doesnotexists
The file /path/to/doesnotexists does not exist.
Usage: …
% open has spaces
The files /path/to/has and /path/to/pyodsdiff/spaces do not exist.
Usage: …
② the file contains a dash:
% open -notanoption
open: invalid option -- n
Usage: …
% open --notanoption
open: invalid option `--notanoption'
Usage: …
③ the variable contains nothing:
% open
Usage: …
So, it looks like it's ③! i.e.: however you're declaring your variable, you're failing to do it.
To test how you're declaring your variable, just use echo instead of open:
% thisfile=README.md echo $thisfile
% thisfile=README.md
% echo $thisfile
README.md
% thisotherfile=README.md ; echo $thisotherfile
README.md
If you have newline delimited filenames in a variable called filelist, then I think you would need to do something like this:
echo -e $filelist | while IFS=$'\n' read f; do open "$f"; done

Resources