Remove leading zeros via parameter expansion
# cf. http://codesnippets.joyent.com/posts/show/1816 i=004555 printf "%s\n" "${i}" printf "%s\n" "${i#"${i%%[!0]*}"}" i="${i#"${i%%[!0]*}"}" printf "%s\n" "${i}"
Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world (or not, you can keep them private!)
# cf. http://codesnippets.joyent.com/posts/show/1816 i=004555 printf "%s\n" "${i}" printf "%s\n" "${i#"${i%%[!0]*}"}" i="${i#"${i%%[!0]*}"}" printf "%s\n" "${i}"
orig=( foo bar baz ) # append "foo" to every array item array=( foo bar baz ) array=( "${array[@]/%/foo}" ) echo "${orig[@]}"$'\n'"${array[@]}" # replace last char "r" with "foo" array=( foo bar baz ) array=( "${array[@]/%r/foo}" ) echo "${orig[@]}"$'\n'"${array[@]}" # prepend "foo" to every array item array=( foo bar baz ) array=( "${array[@]/#/foo}" ) echo "${orig[@]}"$'\n'"${array[@]}" # replace "ba" at the beginning with "foo" array=( foo bar baz ) array=( "${array[@]/#ba/foo}" ) echo "${orig[@]}"$'\n'"${array[@]}" # replace any array item matching "b*" with "foo" array=( foo bar baz ) array=( "${array[@]/%b*/foo}" ) echo "${orig[@]}"$'\n'"${array[@]}" # replace any array item matching "*z" with "foo" array=( foo bar baz ) array=( "${array[@]/#*z/foo}" ) echo "${orig[@]}"$'\n'"${array[@]}" # replace any array item matching "*a*" with "foo" array=( foo bar baz ) #array=( "${array[@]/%*a*/foo}" ) array=( "${array[@]/#*a*/foo}" ) echo "${orig[@]}"$'\n'"${array[@]}" # delete a single leading or trailing space from any array item # cf. http://codesnippets.joyent.com/posts/show/1816 array=( " foo" "bar " baz ) array=( "${array[@]/# /}" ) array=( "${array[@]/% /}" ) echo "${orig[@]}"$'\n'"${array[@]}" # further Bash array tips # get the first array item array=( foo bar baz ) array=( "${array[@]:0:1}" ) echo "${orig[@]}"$'\n'"${array[@]}" # get the last array item array=( foo bar baz ) array=( "${array[@]: -1}" ) echo "${orig[@]}"$'\n'"${array[@]}" # get all array items after the first one array=( foo bar baz ) array=( "${array[@]:1}" ) echo "${orig[@]}"$'\n'"${array[@]}" # get the second array item array=( foo bar baz ) array=( "${array[@]:1:1}" ) echo "${orig[@]}"$'\n'"${array[@]}"
# See: # - http://tldp.org/LDP/abs/html/string-manipulation.html#AEN5117 # - http://tldp.org/LDP/abs/html/internalvariables.html#POSPARAMREF # - http://tldp.org/LDP/abs/html/internalvariables.html#IFSREF # - http://tldp.org/LDP/abs/html/parameter-substitution.html#PARAMSUBREF # - cmdparser, http://codesnippets.joyent.com/posts/show/1697 export IFS=$' \t\n' # create a fake command line set -- "First one" "second" "third:one" "" "Fifth: :one" set -- "First one" "second" "third:"$'\n'"one" "" "Fifth: :one" echo $# # number of arguments printf "%s\n" "${@}" # all arguments printf "%s\n" "${1}" # first argument printf "%s\n" "${3}" # third argument printf "%s\n" "${5}" # last argument printf "%s\n" "${@:1}" # all arguments starting with the first printf "%s\n" "${@:2}" # all arguments starting with the second printf "%s\n" "${@:3}" # all arguments starting with the third printf "%s\n" "${@:(-$#):1}" # first argument printf "%s\n" "${@:$#:1}" # last argument printf "%s\n" "${!#}" # last argument printf "%s\n" "${@:1:1}" # first argument printf "%s\n" "${@:3:1}" # third argument printf "%s\n" "${@:5:1}" # fifth argument printf "%s\n" "${@:(-1):1}" # last argument printf "%s\n" "${@:(-2):1}" # second-to-last argument # process one positional parameter at a time without modifying $# or $@ for (( i=1; i <= $#; i++ )); do printf "%s\n" "${@:${i}:1}"; done echo $# # 5 # $# and $@ get modified for (( i=1; i <= $#; i++ )); do echo $i; printf "%s\n" "$1"; shift; done echo $# # 2 set -- "First one" "second" "third:"$'\n'"one" "" "Fifth: :one" # $# and $@ get modified while [[ $# -gt 0 ]]; do printf "%s\n" "$1"; shift; done echo $# # 0
#!/bin/bash export PATH=/usr/bin:/bin:/usr/sbin:/sbin export IFS=$' \t\n' # create a fake command line set -- -abcc -c -zz -flag1="" -flag2=arg -flag3="arg" -flag4='arg1=*,arg2=?,arg3=!' -flag5 '(arg1|arg2|arg3)' -flag6 'arg1=ag,arg2=bg,arg3=cg' -flag7 An\ argument\ with\ spaces\! -flag8='Yet another argument with spaces / * + ` \ ! ' -flag9 ~/Desktop/*.txt filename1 filename2 filename3 #set -- -abcc -c -zz -flag1="" -flag2=arg -flag3="arg" -flag4='arg1=*,arg2=?,arg3=!' -flag5 '(arg1|arg2|arg3)' -flag6 'arg1=ag,arg2=bg,arg3=cg' -flag7 An\ argument\ with\ spaces\! -flag8='Yet another argument with spaces / * + ` \ ! ' -flag9 '~/Desktop/*.txt' filename1 filename2 filename3 printf "%s\n" "$@" | nl #printf "%s" "$@"$'\n' | nl #printf "%s" "${@/%/ }" | nl : <<-'COMMENT' # copy & paste examples for the command line echo "filename1" "filename2" "filename3" | ~/Desktop/cmdparser.txt -abcc -c -zz -flag1 arg -flag2=arg --flag3="arg" -flag4='arg1=*,arg2=?,arg3=!' -flag5 '(arg1|arg2|arg3)' -flag6 'arg1=ag,arg2=bg,arg3=cg' --flag7 An\ argument\ with\ spaces\! -flag8='Yet another argument with spaces / * + ` \ ! ' -flag9 ~/Desktop/*.txt - echo "filename1" "filename2" "filename3" | ~/Desktop/cmdparser.txt -abcc -c -zz -flag1 arg -flag2=arg --flag3="arg" -flag4='arg1=*,arg2=?,arg3=!' -flag5 '(arg1|arg2|arg3)' -flag6 'arg1=ag,arg2=bg,arg3=cg' --flag7 An\ argument\ with\ spaces\! -flag8='Yet another argument with spaces / * + ` \ ! ' -flag9 '~/Desktop/*.txt' - COMMENT # cmdparser usage="usage: $(/usr/bin/basename "$0") [-a] [-b] [-c] [-cc] [-zz] [-flag1 arg] [-flag2 'arg1 arg2 ...'] [-flag3=arg] [-flag4=\"arg1 arg2\"] ..." # define the names of flags as a regular expression # flags are command line options that require arguments flags="(flag1|flag2|flag3|flag4|flag5|flag6|flag7|flag8|flag9)" # define the names of switches as a regular expression # Switches are command line options that do not take arguments. # Make sure multi-char switches precede single-char switches in the regular expression. # Note that the regular expression contains neither the special read-from-stdin switch "-" # nor the special end-of-options switch "--". switches="(cc|zz|a|b|c)" declare flag1 flag2 flag3 flag4 flag5 flag6 flag7 flag8 flag9 # flags declare -i a=0 b=0 c=0 cc=0 zz=0 # switches declare argstr argvar argvar_escaped char flagvar optstr piped pipedstr # script variables declare -i optid pipedvar # piped="piped" will be used for variable creation # example: piped="piped"; pipedstr="piped arg"; eval $piped='"$(echo "$pipedstr")"'; echo "$piped" piped="piped" # default value is set to "no pipe" pipedvar=0 pipedstr="" # if /dev/stdin has a size greater than zero ... if [[ -s /dev/stdin ]]; then pipedstr="$(</dev/stdin)"; fi if [[ $# -eq 0 ]] && [[ -z "$pipedstr" ]]; then printf "\n%s\n\n%s\n\n" 'No arguments specified!' "$usage" 1>&2 exit 1 fi if [[ $# -eq 0 ]] && [[ -n "$pipedstr" ]]; then eval $piped='"${pipedstr}"' pipedvar=1 fi # if there are command line arguments ... # Note that $pipedvar may still be set to 1 below if the special read-from-stdin switch "-" is given. if [[ $pipedvar -eq 0 ]]; then optstr=" " optid=0 while [[ -n "$optstr" ]]; do # try to extract valid flags or switches from positional parameter $1 # $1 gets shifted afterwards (cf. help shift) optstr="$(printf "%s" "$1" | /usr/bin/egrep -e "^--?${flags}$")" if [[ -n "$optstr" ]]; then optid=1; fi if [[ -z "$optstr" ]]; then optid=2; optstr="$(printf "%s" "$1" | /usr/bin/egrep -e "^--?${switches}$")"; fi if [[ -z "$optstr" ]]; then optid=3; optstr="$(printf "%s" "$1" | /usr/bin/egrep -e "^--?${switches}+$")"; fi if [[ -z "$optstr" ]]; then optid=4; optstr="$(printf "%s" "$1" | /usr/bin/egrep -e "^--?(${flags}=.*|${flags}[^[:space:]]+)$")"; fi if [[ -z "$optstr" ]]; then if [[ "$1" = "-" ]] && [[ "$@" = "-" ]]; then optid=5 optstr="-" elif [[ -n "$(printf "%s" "${@/%/ }" | /usr/bin/egrep -e "[[:space:]]--?(${flags}|${switches})")" ]]; then # append a space to each command line argument argstr="$(printf "%s" "${@/%/ }")" printf "\n%s\x21\n\n%s\n\n%s\n\n" "Undefined non-option string: ${1} is followed by a legal flag or switch" "${argstr}" "$usage" 1>&2 exit 1 fi fi if [[ "$1" = "--" ]]; then shift; break; fi # -- marks end of options if [[ -z "$optstr" ]]; then break; fi # no further flags or switches to process # flag followed by space (example: -f file) if [[ $optid -eq 1 ]]; then if [[ -z "$2" ]]; then printf "%s\n%s\n" "no argument given to flag: ${1}" "$usage" 1>&2 exit 1 fi flagvar="${1##*-}" # remove leading - or -- argvar="$2" eval $flagvar='"${argvar}"' shift 2 # shift positional parameters $1 & $2 (that is, a flag plus its argument) continue # single switch (example: -a) elif [[ $optid -eq 2 ]]; then flagvar="${1##*-}" eval $flagvar='"1"' shift continue # combined switch (example: -abcc) elif [[ $optid -eq 3 ]]; then flagvar="${1##*-}" while [[ -n "$flagvar" ]]; do char="$(printf "%s" "$flagvar" | /usr/bin/sed -E "s/^${switches}.*$/\1/")" eval $char='"1"' flagvar="$(printf "%s" "$flagvar" | /usr/bin/sed -E "s/^${switches}//")" done shift continue # flag without following space (example: -ffile) elif [[ $optid -eq 4 ]]; then : <<-'COMMENT' argvar="$(printf "%s" "$1" | /usr/bin/sed -E "s/^\-\-?${flags}\=?//")" argvar2="${argvar//\\\\/\\\\}" # escape \ (for Bash version 2.05b.0(1)-release) #argvar2="${argvar//\\/\\\\}" # escape \ flagvar="${1%${argvar2}}" # remove escaped $argvar string flagvar="${flagvar%=}" # remove trailing = flagvar="${flagvar##*-}" # remove leading - or -- eval $flagvar='"${argvar}"' shift continue COMMENT # alternative: no string escaping necessary #argvar="$(printf "%s" "$1" | /usr/bin/sed -E "s/^\-\-?${flags}\=?//")" #flagvar="$(printf "%s" "$1" | /usr/bin/sed -E -n -e "s/^\-\-?${flags}\=?.*$/\\1/p")" argvar="$(printf "%s" "${1##*-}" | /usr/bin/sed -E "s/^${flags}\=?//")" flagvar="$(printf "%s" "${1##*-}" | /usr/bin/sed -E -n -e "s/^${flags}\=?.*$/\\1/p")" eval $flagvar='"${argvar}"' shift continue # the special read-from-stdin switch "-" elif [[ $optid -eq 5 ]]; then pipedvar=1 eval $piped='"${pipedstr}"' shift break fi # remove positional parameter $1 from "$@" shift done fi # if [[$pipedvar -eq 0 ]]; then ... echo printf "%s\t%s\n" "a:" "${a}" printf "%s\t%s\n" "b:" "${b}" printf "%s\t%s\n" "c:" "${c}" printf "%s\t%s\n" "cc:" "${cc}" printf "%s\t%s\n" "zz:" "${zz}" printf "%s\t%s\n" "flag1:" "${flag1}" printf "%s\t%s\n" "flag2:" "${flag2}" printf "%s\t%s\n" "flag3:" "${flag3}" printf "%s\t%s\n" "flag4:" "${flag4}" printf "%s\t%s\n" "flag5:" "${flag5}" printf "%s\t%s\n" "flag6:" "${flag6}" printf "%s\t%s\n" "flag7:" "${flag7}" printf "%s\t%s\n" "flag8:" "${flag8}" printf "%s\t%s\n" "flag9:" "${flag9}" echo if [[ $pipedvar -eq 1 ]] && [[ -z "$@" ]]; then echo "remaining string-piped: ${piped}" else echo "remaining string: ${@}" fi echo if [[ $flag9 == '~/Desktop/*.txt' ]]; then printf "%s\n" ~/Desktop/*.txt | nl; fi echo exit 0
#!/bin/bash # create a fake command line #set -- -abcc -c -zz -flag1="" -flag2=arg$'\n'plus_newline -flag3="arg" -flag4='arg1=*,arg2=?,arg3=!' -flag5 '(arg1|arg2|arg3)' -flag6 'arg1=ag,arg2=bg,arg3=cg' -flag7 An\ argument\ with\ spaces\! -flag8='Yet another argument with spaces / * + ` \ !' -flag9 ~/Desktop/*.txt filename1 filename2 filename3 #set -- -abcc -c -zz -flag1="" -flag2=arg$'\n'plus_newline -flag3="arg" -flag4='arg1=*,arg2=?,arg3=!' -flag5 '(arg1|arg2|arg3)' -flag6 'arg1=ag,arg2=bg,arg3=cg' -flag7 An\ argument\ with\ spaces\! -flag8='Yet another argument with spaces / * + ` \ !' -flag9 '~/Desktop/*.txt' filename1 filename2 filename3 printf "%s\n" "$@" | nl #printf "%s" "$@"$'\n' | nl #printf "%s" "${@/%/ }" | nl : <<-'COMMENT' # copy & paste examples echo "filename1" "filename2" "filename3" | ~/Downloads/Mac-OS-X-bash-scripts/bash-cmdparser/cmdparser-non-destructive-1.txt -abcc -c -zz -flag1 arg -flag2=arg$'\n'plus_newline --flag3="arg" -flag4='arg1=*,arg2=?,arg3=!' -flag5 '(arg1|arg2|arg3)' -flag6 'arg1=ag,arg2=bg,arg3=cg' --flag7 An\ argument\ with\ spaces\! -flag8='Yet another argument with spaces / * + ` \ !' -flag9 ~/Desktop/*.txt - echo "filename1" "filename2" "filename3" | ~/Downloads/Mac-OS-X-bash-scripts/bash-cmdparser/cmdparser-non-destructive-1.txt -abcc -c -zz -flag1 arg -flag2=arg$'\n'plus_newline --flag3="arg" -flag4='arg1=*,arg2=?,arg3=!' -flag5 '(arg1|arg2|arg3)' -flag6 'arg1=ag,arg2=bg,arg3=cg' --flag7 An\ argument\ with\ spaces\! -flag8='Yet another argument with spaces / * + ` \ !' -flag9 '~/Desktop/*.txt' - COMMENT echo echo "Number of positional parameters: ${#}" echo # cmdparser export PATH=/usr/bin:/bin:/usr/sbin:/sbin export IFS=$' \t\n' # non-builtin commands used # cf. man builtin declare basename=/usr/bin/basename egrep=/usr/bin/egrep sed=/usr/bin/sed # define the names of flags as a regular expression # flags are command line options that require arguments flags="(flag1|flag2|flag3|flag4|flag5|flag6|flag7|flag8|flag9)" # define the names of switches as a regular expression # Switches are command line options that do not take arguments. # Make sure multi-char switches precede single-char switches in the regular expression. # Note that the regular expression contains neither the special read-from-stdin switch "-" # nor the special end-of-options switch "--". switches="(cc|zz|a|b|c)" usage="usage: $(${basename} "$0") [-a] [-b] [-c] [-cc] [-zz] [-flag1 arg] [-flag2 'arg1 arg2 ...'] [-flag3=arg] [-flag4=\"arg1 arg2\"] ..." declare flag1 flag2 flag3 flag4 flag5 flag6 flag7 flag8 flag9 # flags declare -i a=0 b=0 c=0 cc=0 zz=0 # switches declare argn argstr argvar argvar_escaped char flagvar optstr piped pipedstr # script variables declare -i optid pipedvar # piped="piped" will be used for variable creation # example: piped="piped"; pipedstr="piped arg"; eval $piped='"$(echo "$pipedstr")"'; echo "$piped" piped="piped" # default value is set to "no pipe" pipedvar=0 pipedstr="" # if /dev/stdin has a size greater than zero ... if [[ -s /dev/stdin ]]; then pipedstr="$(</dev/stdin)"; fi if [[ $# -eq 0 ]] && [[ -z "$pipedstr" ]]; then printf "\n%s\n\n%s\n\n" 'No arguments specified!' "$usage" 1>&2 exit 1 fi if [[ $# -eq 0 ]] && [[ -n "$pipedstr" ]]; then eval $piped='"${pipedstr}"' pipedvar=1 fi # if there are command line arguments ... # Note that $pipedvar may still be set to 1 below if the special read-from-stdin switch "-" is given if [[ $pipedvar -eq 0 ]]; then optstr=" " optid=0 # processing one positional parameter at a time without modifying $# or $@ # Process positional parameters non-destructively in Bash, http://codesnippets.joyent.com/posts/show/1706 for (( i=1; i <= $#; i++ )); do argn="${@:${i}:1}" # current positional parameter # "${@:(${i}+1):1}": the positional parameter following the current one # "${@:${i}}": all positional parameters starting with the current one if [[ ${argn:0:1} != '-' ]]; then break; fi # every flag or switch has to have a leading - optstr="$(printf "%s" "${argn}" | ${egrep} -e "^--?${flags}$")" if [[ -n "$optstr" ]]; then optid=1; fi if [[ -z "$optstr" ]]; then optid=2; optstr="$(printf "%s" "${argn}" | ${egrep} -e "^--?${switches}$")"; fi if [[ -z "$optstr" ]]; then optid=3; optstr="$(printf "%s" "${argn}" | ${egrep} -e "^--?${switches}+$")"; fi if [[ -z "$optstr" ]]; then optid=4; optstr="$(printf "%s" "${argn}" | ${egrep} -e "^--?(${flags}=.*|${flags}[^[:space:]]+)$")"; fi if [[ -z "$optstr" ]]; then if [[ "${argn}" = "-" ]] && [[ "${@:${i}}" = "-" ]]; then optid=5 optstr="-" elif [[ -n "$(printf "%s" "${@:${i}/%/ }" | ${egrep} -e "[[:space:]]--?(${flags}|${switches})")" ]]; then # create argstr by appending a space to each command line argument argstr="$(printf "%s" "${@:${i}/%/ }" )" printf "\n%s\x21\n\n%s\n\n%s\n\n" "Undefined non-option string: ${argn} is followed by a legal flag or switch" "${argstr}" "$usage" 1>&2 exit 1 fi fi if [[ "${argn}" = "--" ]]; then break; fi # -- marks end of options if [[ -z "$optstr" ]]; then break; fi # no further flags or switches to process # flag followed by space (example: -f file) if [[ $optid -eq 1 ]]; then if [[ -z "${@:(${i}+1):1}" ]]; then printf "%s\n%s\n" "no argument given to flag: ${argn}" "$usage" 1>&2 exit 1 fi flagvar="${argn##*-}" # remove leading dashes argvar="${@:(${i}+1):1}" eval $flagvar='"${argvar}"' let "i += 1" # skip argument of current flag in next for loop continue # single switch (example: -a) elif [[ $optid -eq 2 ]]; then flagvar="${argn##*-}" eval $flagvar='"1"' continue # combined switch (example: -abcc) elif [[ $optid -eq 3 ]]; then flagvar="${argn##*-}" while [[ -n "$flagvar" ]]; do char="$(printf "%s" "$flagvar" | ${sed} -E "s/^${switches}.*$/\1/")" eval $char='"1"' flagvar="$(printf "%s" "$flagvar" | ${sed} -E "s/^${switches}//")" done continue # flag without following space (example: -ffile) elif [[ $optid -eq 4 ]]; then : <<-'COMMENT' argvar="$(printf "%s" "${argn}" | ${sed} -E "s/^\-\-?${flags}\=?//")" argvar2="${argvar//\\\\/\\\\}" # escape \ (for Bash version 2.05b.0(1)-release) #argvar2="${argvar//\\/\\\\}" # escape \ flagvar="${argn%${argvar2}}" # remove escaped $argvar string flagvar="${flagvar%=}" # remove trailing = flagvar="${flagvar##*-}" # remove leading - or -- eval $flagvar='"${argvar}"' continue COMMENT # alternative: no string escaping required #argvar="$(printf "%s" "${argn}" | ${sed} -E "s/^\-\-?${flags}\=?//")" #flagvar="$(printf "%s" "${argn}" | ${sed} -E -n -e "s/^\-\-?${flags}\=?.*$/\\1/p")" argvar="$(printf "%s" "${argn##*-}" | ${sed} -E "s/^${flags}\=?//")" flagvar="$(printf "%s" "${argn##*-}" | ${sed} -E -n -e "s/^${flags}\=?.*$/\\1/p")" eval $flagvar='"${argvar}"' continue # the special read-from-stdin switch "-" elif [[ $optid -eq 5 ]]; then pipedvar=1 eval $piped='"${pipedstr}"' break fi done # for loop fi # if [[$pipedvar -eq 0 ]]; then ... echo printf "%s\t%s\n" "a:" "${a}" printf "%s\t%s\n" "b:" "${b}" printf "%s\t%s\n" "c:" "${c}" printf "%s\t%s\n" "cc:" "${cc}" printf "%s\t%s\n" "zz:" "${zz}" printf "%s\t%s\n" "flag1:" "${flag1}" printf "%s\t%s\n" "flag2:" "${flag2}" printf "%s\t%s\n" "flag3:" "${flag3}" printf "%s\t%s\n" "flag4:" "${flag4}" printf "%s\t%s\n" "flag5:" "${flag5}" printf "%s\t%s\n" "flag6:" "${flag6}" printf "%s\t%s\n" "flag7:" "${flag7}" printf "%s\t%s\n" "flag8:" "${flag8}" printf "%s\t%s\n" "flag9:" "${flag9}" echo if [[ $pipedvar -eq 1 ]] && [[ -z "$@" ]]; then echo "remaining string-piped: ${piped}" else echo "remaining string: ${@}" fi echo echo "Number of positional parameters: ${#}" echo if [[ $flag9 == '~/Desktop/*.txt' ]]; then printf "%s\n" ~/Desktop/*.txt | nl; fi echo exit 0
post :process_checkout, YAML.load(<<-END.gsub(/^\s*\|/, "")).symbolize_keys |--- |card: | number: "4242424242424242" | month: 8 | year: 2010 | first_name: Test | last_name: Customer | type: visa END