Reputation: 24535
I want to create a script that can be given 3 arguments: task, infile-type, outfile-type; and it should apply the task to each of such files in the folder. For example, I should be able to give command: convert png jpg
, and it should convert all png files to jpg in the folder. I should also be able to send options with task, enclosed in quotes, e.g.: "convert -o myoption" png jpg
I tried:
#! /bin/bash
for f in *.$2
do
$1 "$f" -o "${f%.$2}.$3"
done
Will above work or do I need to enclose $1 etc in {} or []? I have not tried it since, if erroneous, it may cause unpredictable damage to files. Thanks for your help.
Upvotes: 2
Views: 454
Reputation: 23824
Move the command to the end of your argument list.
#! /bin/bash
src=$1; shift
dst=$1; shift
for f in *."$src"
do
"$@" "$f" -s -o "${f%.$src}.$dst"
done
Then the arguments get correctly quoted
my-script png jpg convert -o myoption
even, if the arguments contain spaces.
my-script png jpg convert --some-option "argument with spacees"
Upvotes: 1
Reputation: 207465
You can express that quite readily with GNU Parallel and have the added benefit of all the tasks being run in parallel too:
parallel convert {} {.}.png ::: *.jpg
where {}
replaces the argument and {.}
represents the argument without extension.
As regards your concern for doing something potentially dangerous, use --dry-run
to test out what it would do, without actually doing anything:
parallel --dry-run convert -o XYZ {} {.}.png ::: *.jpg
Sample Output
convert -o XYZ a.jpg a.png
convert -o XYZ a\ g.jpg a\ g.png
convert -o XYZ b.jpg b.png
Upvotes: 3
Reputation: 25023
An useful technique while writing shell scripts that may have dangerous results
simply consists in using the echo
builtin.
Your code is substantially correct, I'd just use a bit of extra quoting and a test to exclude the possibility of action on non existing files (even if this is more cosmetic...)
repeat() { for f in *.$2 ; do
[ -f "$f" ] && echo $1 \"$f\" \"${f%.$2}.$3\"
done ; }
Here it is a short terminal session to show how it works
$ ls
a b.png a.png b.png
$ repeat() { for f in *.$2 ; do [ -f "$f" ] && echo $1 \"$f\" \"${f%.$2}.$3\" ; done ; }
$ repeat 'cp -f' pmg jpg #### typinh error
$ repeat 'cp -f' png jpg
cp -f "a b.png" "a b.jpg"
cp -f "a.png" "a.jpg"
cp -f "b.png" "b.jpg"
$ repeat 'cp -f' png jpg | sh
$ ls
a b.jpg a b.png a.jpg a.png b.jpg b.png
$
When you are 99.9% sure of your code, remove the echo
and there you are...
Upvotes: 1
Reputation: 499
I guess you want to have a list of files in your folder. You may try that. Let me now if there are some errors so I may can change it to what you exactly want
#! /bin/bash
# Command which should performed
echo $1
# File type IN
echo $2
# File type OUT
echo $3
for i in $(ls)
do
$1 $2 $3 $i
done
Upvotes: 1