linux - Bash - variables are not evaluated inside other variables -
i've written short script needs find text using regex.
i'm incrementing counter inside while loop, , counter part of command. unfortunately command running initial counter.
here snippet code:
counter=1 last_commit=`git log remotes/origin/devel --pretty=oneline --pretty=format:%s | head -${counter}` jira_id=`echo $last_commit | grep -o -p '[a-z]{2,}-\d+' | xargs` while [[ ! -z "$jira_id" && $counter -lt "5" ]]; echo "this current counter: $counter" echo "this last commit $last_commit" counter=$[counter+1] done echo "this counter outside loop $counter"
the best-practices way encapsulate code (as per bashfaq #50) function:
get_last_commit() { git log remotes/origin/devel --pretty=oneline --pretty=format:%s \ | sed -n "$(( $1 + 1)) p" }
then:
while (( counter < 5 )); last_commit=$(get_last_commit "$counter") ifs=$'\n' read -r -d '' -a jira_id \ < <(grep -o -p '[a-z]{2,}-\d+' <<<"$last_commit") ||: [[ $jira_id ]] || break echo "this current counter: $counter" echo "this last commit $last_commit" echo "found ${#jira_id[@]} jira ids" printf ' %s\n' "${jira_id[@]}" (( counter++ )) done
other notes:
- use of
read -a
, here, reads jira ids array; can ask array's length (with${#jira_id[@]}
), expand specific entry array (with${jira_id[0]}
first id,[1]
second, etc); expand them argument list (with"${jira_id[@]}"
), etc. - non-system-defined shell variables should have @ least 1 lower-case character in names. see fourth paragraph of posix spec on environment variables @ http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html, keeping in mind environment variables , shell variables share single namespace. following practice prevents overwriting system variables mistake.
$(( ... ))
posix-standard way enter math context;(( ))
, without leading$
, bash extension.- while code inside of
[[ ]]
,(( ))
not require double quotes prevent glob expansion or string-splitting, double quotes should used around expansions in (almost) other cases. sed '2 p'
gets line 2 more efficientlyhead -2 | tail -n 1
.
however, less efficient calling git log
1 single time , iterating on results.
while ifs= read -r -u 3 last_commit; ifs=$'\n' read -r -d '' -a jira_id \ < <(grep -o -p '[a-z]{2,}-\d+' <<<"$last_commit") ||: [[ $jira_id ]] || continue echo "found ${#jira_id[@]} jira ids" printf ' %s\n' "${jira_id[@]}" done 3< <(git log remotes/origin/devel --pretty=oneline --pretty=format:%s)
Comments
Post a Comment