![](/img/trans.png)
[英]How to pipe while loop input to the encapsulated commands after the “do”
[英]How to use while loop inside subshell after pipe
我一直在尋找解決方案,但是找不到任何直接解決我問題的方法。 我正在嘗試將某些作者在git repo中添加和刪除的行加起來。 我正在使用git log通過管道傳輸到sed,通過管道傳輸到awk,現在我試圖通過管道傳輸到子外殼以將數字相加。 問題在於,在子shell中無法正確解釋管道輸入,並且我不知道為什么。 我懷疑它處於while循環中,因為subshell語法的性質以及對分號的挑剔性。
我在子外殼中移動了代碼,添加和刪除了分號,使用反斜杠進行行分隔以查看是否是問題所在,但都沒有起作用。 我不太精通Shell,因此對於經驗豐富的人來說,這可能是一個顯而易見的問題。 “ $ author”只是命令行中的第n個位置參數。
for author; do
echo "Listing file and line changes for $author"
git log --shortstat --author="$author" ${date:+--since="$date"} \
| sed -n -e '/files\? changed/s/, /\n/gp' \
| awk '
$3=="changed" {changed+=$1}
$2=="deletions(-)" {deletions+=$1}
$2=="insertions(+)" {insertions+=$1}
END{
print "files changed:", changed,
" lines removed:", deletions,
" lines added:", insertions,
" net change:", insertions-deletions
}'
done | {
total_changed=0
total_added=0
total_removed=0
while read changed insertions deletions; do
let total_changed+=changed
let total_added+=insertions
let total_removed+=deletions
done
echo "totals:"
echo "files changed: $total_changed"
echo "lines added: $total_added"
echo "lines removed: $total_removed" ;
}
最后一部分應輸出總計,但輸出0。我還會遇到一些奇怪的語法錯誤。 這是輸出(輸入是“ Benjamin Hills”):
/home/bhills/./git-log-lines-removed.sh: line 65: let: and line changes for Benjamin Hills: syntax error in expression (error token is "line changes for Benjamin Hills")
/home/bhills/./git-log-lines-removed.sh: line 64: let: changed:: syntax error in expression (error token is ":")
/home/bhills/./git-log-lines-removed.sh: line 65: let: 61 lines removed: 1345 lines added: 246 net change: -1099: syntax error in expression (error token is "lines removed: 1345 lines added: 246 net change: -1099")
totals:
files changed: 0
lines added: 0
lines removed: 0
您的代碼嘗試生成兩次人類可讀的輸出:一次進入awk,另一次進入bash。 由於awk
生成的輸出是輸入到bash
,這意味着您試圖通過管道傳遞供人類使用的輸出格式,並像將其作為供機器使用的輸入格式一樣讀取它; 顯然不是。
完全沒有理由采用這種方法:在同一過程中生成所有人類可讀的輸出。
#!/usr/bin/env bash
# ^^^^- NOT /bin/sh
total_changed=0
total_deletions=0
total_insertions=0
for author; do
changed=0; deletions=0; insertions=0
# Loop over output from "git log" for a single author
while read added deleted _; do
(( ++changed )) # each line is a file changed
{ [[ $added = - ]] || [[ $deleted = - ]]; } && continue # skip binary files
(( insertions += added ))
(( deletions += deleted ))
done < <(git log --numstat --format='' --author="$author" ${date:+--since="$date"})
# Print results from that author
printf '%s\n' "For author: $author" \
" Files changed: $changed" \
" Deletions: $deletions" \
" Insertions: $insertions"
# Add to totals
(( total_changed+=changed ))
(( total_deletions+=deletions ))
(( total_insertions+=insertions ))
done
# Print those totals
printf '%s\n' "Totals:" \
" Files changed: $total_changed" \
" Deletions: $total_deletions" \
" Insertions: $total_insertions"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.