I have this line as one of many in a file
show = "holder"; // [holder: Dispensor,dryer: Hair Dryer,bidet: Bedit,cover: Cover,wall mount: Wall Mount,screwdriver cutout: Screwdriver Cutout, assembly: Assembly,exploded: Exploded,vitamin: Vitamin]
What I want is to generate a shell script file where for each xxx:yyy pair generate the following line:
openscad --quite --export-format --D 'show=xxx' binstl -o xxx.stl $1
The $1 above is for the first parameter of a shell script.
I have tried this code:
match($0, /\[[^\n\]]*\]$/) { # get [xx:yy, aa:bb]
s = substr($0, RSTART+1, RLENGTH-2); # strip the [ and ]
n = split(s, arr,","); # split the pairs
for(x in arr) { # for each pair
match(arr[x], /([^\n:]+)/, b) { # get the first field of the pair
print subsgtr(b[1], RSTART, RLENGTH)
}
}
}
With this result:
gawk: prog:5: match(arr[x], /([^\n:]+)/, b) { # get the first field of the pair
gawk: prog:5: ^ syntax error
I've also tried this:
match($0, /\[[^\n\]]*\]$/) { # get [xx:yy, aa:bb]
s = substr($0, RSTART+1, RLENGTH-2); # strip the [ and ]
n = split(s, arr,","); # split the pairs
for(x in arr) { # for each pair
arr[x] ~ /([^\n:]+)/ print
}
}
gawk: prog:5: arr[x] ~ /([^\n:]+)/ print
gawk: prog:5: ^ syntax error
and this:
match($0, /\[[^\n\]]*\]$/) { # get [xx:yy, aa:bb]
s = substr($0, RSTART+1, RLENGTH-2); # strip the [ and ]
n = split(s, arr,","); # split the pairs
for(x in arr) { # for each pair
arr[x] ~ /([^\n:]+)/ { print }
}
}
gawk: prog:5: arr[x] ~ /([^\n:]+)/ { print }
gawk: prog:5: ^ syntax error
I don't understand why I'm getting the syntax errors. If you show me a different/better solution, if you can, please explain the syntax errors so I can learn more about awk. Thanks!
awk
pattern-action statements are expressed as condition {action}
. You cannot use the same pattern-action form inside an action. Use if
statements, instead. For instance, replace arr[x] ~ /([^\n:]+)/ print
with if(arr[x] ~ /([^\n:]+)/) print
.
For your problem, and with the given example, you could define the input field separator as a regular expression, and skip the first and last fields. Example, with quotes added compared with the expected output (because you have some spaces there), and 2 typos fixed (quiet
and --export-format binstl
):
$ cmd="openscad --quiet --export-format binstl --D 'show=X' -o 'X.stl' \"\$1\""
$ awk -F '[[:space:]]*(.*[[]|:[^,]*[],])[[:space:]]*' -v cmd="$cmd" '
{for(i = 2; i < NF; i++) {c=cmd; gsub(/X/,$i,c); print c}}' file
openscad --quiet --export-format binstl --D 'show=holder' -o 'holder.stl' "$1"
openscad --quiet --export-format binstl --D 'show=dryer' -o 'dryer.stl' "$1"
openscad --quiet --export-format binstl --D 'show=bidet' -o 'bidet.stl' "$1"
openscad --quiet --export-format binstl --D 'show=cover' -o 'cover.stl' "$1"
openscad --quiet --export-format binstl --D 'show=wall mount' -o 'wall mount.stl' "$1"
openscad --quiet --export-format binstl --D 'show=screwdriver cutout' -o 'screwdriver cutout.stl' "$1"
openscad --quiet --export-format binstl --D 'show=assembly' -o 'assembly.stl' "$1"
openscad --quiet --export-format binstl --D 'show=exploded' -o 'exploded.stl' "$1"
openscad --quiet --export-format binstl --D 'show=vitamin' -o 'vitamin.stl' "$1"
Note: another approach would be to write a generic bash script in which you use awk
to feed a loop. In the following example the input file is passed as second parameter ($2
):
#!/usr/bin/env bash
if (( $# != 2 )); then
printf 'usage: %s ARG FILE\n' "${0##*/}"
exit 1
elif ! [[ -f "$2" ]]; then
printf '%s: file not found\n' "$2"
exit 1
fi
awk -F '[[:space:]]*(.*[[]|:[^,]*[],])[[:space:]]*' '
{for(i = 2; i < NF; i++) print $i}' "$2" | while read -r s; do
openscad --quiet --export-format binstl --D "show=$s" -o "$s.stl" "$1"
done