使用readarray bash脚本解析git日志

时间:2015-03-08 00:43:50

标签: bash shell

我正在解析" git log -1 --name-status"的输出。获取上次提交中更改的每个文件的文件扩展名。您可以在http://goo.gl/Ms11a2

上看到一个有效的示例

一旦我开始使用tutorialspoint,我试图在git post-commit钩子中运行它,但是readarray line(#9)引发了语法错误。

  

.git / hooks / post-commit:9:.git / hooks / post-commit:语法错误:重定向意外

你们能指出我正确的方向吗?我做错了什么,为什么它会在http://goo.gl/Ms11a2而不是提交后工作?请原谅我的无知......我对shell脚本没有多少经验。

#!/bin/sh
### git-stats hook (begin) ###
# Copy last commit hash to clipboard on commit
commit_hash=$(git rev-parse HEAD)
repo_url=$(git config --get remote.origin.url)
commit_date=$(git log -1 --format=%cd)
commit_changes=$(git log -1 --name-status)

readarray -t log_lines <<< "$commit_changes"
fileRegex='(.*)\.'
file_changed_start=6;
file_changed_line="${log_lines[file_changed_start]}"
declare -A languages;

# Step through each line that passes the regex
while  [[ "${file_changed_line}" =~ ${fileRegex} ]]; do
    # Store the file extension
    parsePathAndFilename="${BASH_REMATCH[0]}"
    fileExtention=${file_changed_line#${parsePathAndFilename}};
    # Add 1 to the language that is already defined
    let languages[${fileExtention}]++;
    file_changed_start=$(($file_changed_start + 1))
    file_changed_line="${log_lines[file_changed_start]}"
done

# Create the JSON output
fileTypes="{";
fileTypeTotal=${#languages[@])};
assocKeys=(${!languages[@]});

for changed in "${!languages[@]}" 
    do
        if [[ "$changed" == "${assocKeys[fileTypeTotal-1]}" ]]
            then
                fileTypes+="\"$changed\" : ${languages[$changed]}";
            else
                fileTypes+="\"$changed\" : ${languages[$changed]},";
        fi
done

# close off the json
fileTypes+="}";

echo $fileTypes

commit_data="\"{ \"date\": \"$commit_date\", \"url\": \"$repo_url\", \"hash\": \"$commit_hash\", \"languages": \"$fileTypes\" }\""
git-stats --record "${commit_data}"
### git-stats hook (end) ###

1 个答案:

答案 0 :(得分:1)

“here-string”语法(<<<)是bash扩展名;它不存在于基本壳中。 (它不是严格意义上的bash;许多其他shell也使用它。)数组和readarray命令也是如此。

因此,您需要确保使用bash来运行脚本。您的shebang行(#!/bin/sh)告诉系统使用基本shell,如果系统上的基本shell不是bash,则可能没有<<<

尝试将shebang行更改为

#!/bin/bash

(确保这是bash的正确路径。您可以使用which bash进行验证。)