Linux Bash-变量不在其他变量中计算
我写了一个简短的脚本,需要使用正则表达式查找一些文本 我在while循环中递增一个计数器,这个计数器是另一个命令的一部分。不幸的是,此命令总是与初始计数器一起运行 下面是我的代码片段:Linux Bash-变量不在其他变量中计算,linux,bash,shell,unix,Linux,Bash,Shell,Unix,我写了一个简短的脚本,需要使用正则表达式查找一些文本 我在while循环中递增一个计数器,这个计数器是另一个命令的一部分。不幸的是,此命令总是与初始计数器一起运行 下面是我的代码片段: 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,
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" ]]; do
echo "This is the current counter: $COUNTER"
echo "This is the last commit $LAST_COMMIT"
COUNTER=$[COUNTER+1]
done
echo "this is the counter outside the loop $COUNTER"
Bash是一种过程语言,这意味着它包含一系列按顺序执行的步骤
LAST\u COMMIT=`…`
是将变量LAST\u COMMIT
设置为命令值的步骤。您只执行了一次这个步骤,这就是为什么您一遍又一遍地看到相同的值
如果希望它对$COUNTER
的新值再次执行,可以将该语句放入循环中:
while
LAST_COMMIT=`git log remotes/origin/devel --pretty=oneline --pretty=format:%s | head -${COUNTER} | tail -n 1`
JIRA_ID=`echo $LAST_COMMIT | grep -o -P '[A-Z]{2,}-\d+' | xargs`
[[ ! -z "$JIRA_ID" && $COUNTER -lt "5" ]]
do
echo "This is the current counter: $COUNTER"
echo "This is the last commit $LAST_COMMIT"
COUNTER=$[COUNTER+1]
done
echo "this is the counter outside the loop $COUNTER"
由于循环中的步骤被执行多次,因此
LAST_COMMIT=`…`
步骤也被执行多次,每次都使用$COUNTER
的新值 封装代码的最佳实践方法(根据)是使用以下函数:
get_last_commit() {
git log remotes/origin/devel --pretty=oneline --pretty=format:%s \
| sed -n "$(( $1 + 1)) p"
}
然后:
您只需运行一次命令。初始值为
$COUNTER
。如果需要使用不同的值运行它,则需要再次运行它。LAST\u COMMIT
和JIRA\u ID
在设置后都不会更改。另外,| xargs
在那里可能毫无意义,因为它只是/bin/echo
;每次需要获取新的LAST\u COMMIT
值时,都需要运行该命令。在循环之前不止一次。每次你想要获得一个新的JIRA\u ID
值(来自一个新的LAST\u COMMIT
值)时,都会发生同样的事情。@AlG No.糟糕。这里甚至根本不需要eval。您还可以告诉git log
直接输出多少个条目,而不需要head
。每次你的计数器
递增时,这将从git log
中获得越来越多的输出行,我认为这不是你想要的。(我还认为,--pretty=format
正在重写--pretty=oneline
,因此您可能不需要两者。)我认为这是一种解决方法,因为如果第一次提交包含JIRA ID,则while不应运行,如果我不需要,请更正wrong@user3502786我没有注意到,但它仍然是相同的概念。您需要循环中的语句。我已经更新了。所以我们需要在这里复制一个代码,这是不正确的good@user3502786你在哪里看到重复代码?while中的条件应该是,除非Jira ID为空,否则继续循环,计数器<5只是为了演示,我不想得到无限循环。顺便问一下,您建议如何避免使用xargs应该是,
?你错过了什么。无论如何,请参见[[$jira_id]]| | break
,如果jira_id
在分配后一直为空,则它将停止循环。将该条件放入而本身意味着您永远不会进入循环开始,因为变量在循环的第一次迭代运行之前是空的!是的,但我不能使用计数器<5作为循环终止,因为我不知道需要扫描多少个提交,然后使用而不是true
。这就是我的想法,避免xargs怎么样
while (( counter < 5 )); do
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 is the current counter: $counter"
echo "This is the last commit $last_commit"
echo "Found ${#jira_id[@]} jira IDs"
printf ' %s\n' "${jira_id[@]}"
(( counter++ ))
done
while IFS= read -r -u 3 last_commit; do
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)