1

I'm writing a script to merge the xkcd webcomic tiles for comic 1110. So far, I have written about 100 lines, and instead of doing each quadrant of the image separately, I've decided to use functions to do this, repeating for every quadrant and using variables for each quadrant to make the function act differently each time. I would like to be able to something like this, except do it with a different value for a each time.

a='((n=$north; n>=1; n--))'; for ${a}; do "echo Hello World!" done 

My problem is, I'm having trouble using variables for the for loop expressions, it goes "line 8: eval "$a"': not a valid identifier", and if I try putting it in parentheses, it goes "line 30: syntax error: arithmetic expression required", and then "line 30: syntax error: `((${a}))". This is what I have so far. Before anyone answers, Yes, I know it has bugs.

#!/bin/bash # Date Created: September 20th, 2012 # Created by Jonathan Bondhus - https://github.com/jbondhus # Credit to Andreas Reichinger for analysis of image tile placement, xkcd.com for comic. Used ImageMagick code from Antonio Frascarelli. # # This script will merge the files from xkcd comic number 1110, "Click and Drag". function function_join() { echo "#"; if [[ quadrant -eq 1 ]]; then echo "# First Quadrant:"; # Join together the first quadrant function_quadrant else if [[ quadrant -eq 2 ]]; then echo "# Second Quadrant:"; # Join together the second quadrant function_quadrant else if [[ quadrant -eq 3 ]]; then echo "# Third Quadrant:"; # Join together the third quadrant function_quadrant else if [[ quadrant -eq 4 ]]; then echo "# Fourth Quadrant:"; # Join together the fourth quadrant function_quadrant fi fi fi fi echo "#"; for ${a}; do echo "# row number "$n" ..."; convert $b; for `eval "$c"`; do if [ $d ]; # If the tile file doesn't exist, an empty square will be used. then convert $e; else convert $f; fi; done; convert $g; # Append the image onto the current quadrant rm -f $h; echo "# ... OK"; echo "#"; done; } function function_quadrant() { if [[ quadrant -eq 1 ]]; then # Set the variables for function_join quadrantName="first" a='((n=$north; n>=1)); n--' b='-size 0x1 xc:white resultn$n''w.png' c='((w=$west; w>=1; w--))' d='-e $n''n$w''w.png' e='+append resultn$n''w.png $n''n$w''w.png resultn$n''w.png' f='+append resultn$n''w.png _blank.png resultn$n''w.png' g='-append ${quadrantName}Quadrant.png resultn$n''w.png ${quadrantName}Quadrant.png' h='resultn$n''w.png' else if [[ quadrant -eq 2 ]]; then quadrantName="second" a='n=$north; n>=1; n--' b='-size 0x1 xc:white resultn$n''e.png' c='e=$east; e<=20; e++' d='-e $n''n$e''e.png' e='+append resultn$n''e.png $n''n$e''e.png resultn$n''e.png' f='+append resultn$n''e.png _blank.png resultn$n''e.png' g='-append ${quadrantName}Quadrant.png resultn$n''e.png ${quadrantName}Quadrant.png' h='resultn$n''e.png' else if [[ quadrant -eq 3 ]]; then quadrantName="third" a='s=1; s<=$south; s++' b='-size 0x1 xc:black results$s''w.png' c='w=$west; w>=1; w--' d='-e $s''s$w''w.png' e='+append results$s''w.png $s''s$w''w.png results$s''w.png' f='+append results$s''w.png _black.png results$s''w.png' g='-append ${quadrantName}Quadrant.png results$s''w.png ${quadrantName}Quadrant.png' h='results$s''w.png' else if [[ quadrant -eq 4 ]]; then quadrantName="fourth" a='s=1; s<=$south; s++' b='-size 0x1 xc:black results$s''e.png' c='e=1; e<=20; e++' d='-e $s''s$e''e.png' e='+append results$s''e.png $s''s$e''e.png results$s''e.png' f='+append results$s''e.png _black.png results$s''e.png' g='-append ${quadrantName}Quadrant.png results$s''e.png ${quadrantName}Quadrant.png' h='results$s''e1.png' else # If more than 4 quadrants, just to be safe, exit exit 1 fi fi fi fi } for (( quadrant = 0; quadrant < 4; quadrant++ )); do function_join done echo "#################################" echo "Joining completed!" echo "#################################" exit 0 
1
  • not sure why you don't use elif or better yet, case ${quad} in first ) do stuff ;; second ) do ... ;; ... esac. I don't think you need all that indenting, just makes it hard to follow along with what you're doing. that said, interesting problem, consider a rewrite in awk with an occasional call like cmd="convert " opt1 opt2 opt3 ..; system(cmd) ; ... . Good luck. Commented Sep 22, 2012 at 3:08

2 Answers 2

1
./north.sh Hello World! 4 5 Hello World! 3 4 Hello World! 2 3 Hello World! 1 2 Hello World! 0 1 

cat north.sh

#!/bin/bash north=5; for ((n=$north; n>=1; --n)) do ((north--)) echo "Hello World! $north $n" done 
Sign up to request clarification or add additional context in comments.

Comments

0

Afraid not. Syntax parsing occurs prior to parameter expansion (parameters need to be first recognized as such, after all). I would recommend restructuring your code to pass around data, not executable code.

1 Comment

So what specifically are you thinking? Write it out non-looping? Or nested if statements?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.