xml - bash 读取 git 日志并将其打印为 .xml 格式 (RSS)

标签 xml git bash rss

我正在尝试创建一个脚本来读取 git log 的输出并将其放置为一个 XML 文件。

这是脚本的示例。

#!/bin/bash
repo=(/srv/git/repositories)
list1=($repo/test.git)
cd "$list1"

echo '<?xml version="1.0" ?><rss version="2.0"><channel>' >> /tmp/test.xml
for i in $(git log --pretty=format:"%h")
do
   for e in $(git log | grep "Author:" | awk '{print $2}')
   do
      #for f in $(git log --pretty=format:"%cn")
      #do
         #for g in $(git log --pretty=format:"%cD")
         #do
         cat << EOF >> /tmp/test.xml
         <item><title>$i</title><description></description><author>$e</author><pubDate></pubDate></item>
         EOF
         #done
      #done
     done
done
echo '</channel></rss>' >> /tmp/test.xml

当我这样做时,结果是每个提交号和作者将被多次读取和回显。所以我会得到一个像这样的 .xml 文件: 很多相同的提交号!

<rss version="2.0">
<channel>
   <item>
      <title>906feb6</title>
      <description/>
      <author>test</author>
      <pubDate/>
   </item>
   <item>
      <title>906feb6</title>
      <description/>
      <author>test</author>
      <pubDate/>
   </item>
   <item>
      <title>906feb6</title>
      <description/>
      <author>test</author>
      <pubDate/>
   </item>
   <item>
      <title>**906feb6**</title>
       <description/>
       <author>test1</author>
       <pubDate/>
    </item>
    <item>
       <title>**906feb6**</title>
       <description/>
       <author>test1</author>
       <pubDate/>
    <item>
    <title>**ffb521e**</title>
       <description/>
       <author>test1</author>
       <pubDate/>
    </item>
<channel></rss>

我想要的是每个提交编号都有作者、描述和发布日期。但它必须从这些命令中获取信息。

我想要这样的输出,有人可以帮忙吗?

<item>
   <title>906feb6</title>
   <description/>test commit 1</description>
   <author>test1</author>
   <pubDate>Mar, 18<pubDate/>
<item>
   <title>**ffb521e**</title>
   <description>test commit 2</description>
   <author>test2</author>
   <pubDate>Mar, 18<pubDate/>
</item>

最佳答案

@EtanReisner pointed out ,您将循环遍历内部循环中的所有提交,而不仅仅是外部for循环正在处理的提交。

以下是如何避免 for 循环并解决该问题的方法。

#!/bin/sh
echo '<?xml version="1.0" ?><rss version="2.0"><channel>' > /tmp/test.xml  # Make sure we start with an empty file
git log --pretty=format:"%h" |
while read -r i; do
   # Presumably you want a single commit here
   # See also https://stackoverflow.com/a/4082178/874188
   # Also avoid Useless Use of grep
   e=$(git log "$i" -1 | awk '/^Author:/{print $2}')
   cat <<____EOF >> /tmp/test.xml
     <item><title>$i</title><description></description><author>$e</author><pubDate></pubDate></item>
____EOF
done
echo '</channel></rss>' >> /tmp/test.xml

我认为没有理由在开始时将存储库放入两个(原文如此!)数组中。 (如果它只是一个值,为什么要使用数组?)只需在您想要处理的任何存储库中运行它即可。

解决了这个问题,这个脚本中就没有 Bashisms,所以我将 shebang 更改为 #!/bin/sh

要将描述等也放入代码片段中,可能是这样的(为了易读而包装;应该只有一行):

git log "$i" -1 --format=format:"<item>%n <title>%h</title>
    %n <description>%s</description>%n <author>%an</author>
    %n <pubDate>%ad</pubDate>%n</item>"

(2021 年更新)

...但我猜你实际上想要的只是类似的东西

#!/bin/sh
echo '<?xml version="1.0" ?><rss version="2.0"><channel>' > /tmp/test.xml
git log --format=format:"<item>%n <title>%h</title>%n <description>%s</description>%n <author>%an</author>%n <pubDate>%ad</pubDate>%n</item>" >>/tmp/test.xml
# TODO: escape XML specials
echo '</channel></rss>' >> /tmp/test.xml

当您已经拥有(可能格式错误)XML 片段时转义 XML 字符有点棘手,因此可以将 git log --format 替换为更简单的内容,您可以将其提供给 Awk 或 Perl 进行进一步处理。为了稳健性,您可能想要输出以 null 分隔的字段,但常规的非 GNU Awk 无法可靠地处理这些字段,因此可能会使用 Perl。这是一个稍微快速但肮脏的尝试:

git log --format=format:'title:%h%x00description:%s%x00author:%an%x00pubDate:%ad%x00' |
perl -0ne 'BEGIN {
    print("<?xml version="1.0" ?><rss version="2.0"><channel>\n");
  }
  @s = /^([^:]+):(.*)/;
  $f[$i] = $s[0]; $fld[$i] = $s[1];
  # Escape XML specials &<>
  $fld[$i] =~ s/&/\&amp;/g; $fld[$i] =~ s/</\&lt;/g; $fld[$i] =~ s/>/\&gt;/g;
  # Print when we have gathered a full record
  if ($i++ == 3) { print "<item>\n";
    for my $field (0..$i-1) {
      print("  <$f[$field]>$fld[$field]</$f[$field]>\n");
    } print "</item>\n";
  @f = @fld = (); $i = 0 }
END { print("</channel></rss>\n"); }' >/tmp/text.xml

关于xml - bash 读取 git 日志并将其打印为 .xml 格式 (RSS),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29127493/

相关文章:

bash - shell 内置工具

c++ - 帮助编辑代码以修复 "Argument list too long"错误

bash - 如何将原始模数和指数转换为 RSA 公钥(.pem 格式)

xml - XML 中的外部引用 DTD

Git:我不 promise 在 origin/master 之前的分支如何

svn - 使用 Git SVN 追溯更正作者?

linux - 无法以普通用户身份推送到 git 存储库

c# - 如何将xml文件绑定(bind)到Gridview

sql-server - SQL Server 2005 中的 XML?在 Varchar 中比 JSON 更好?

ios - NSDictionary长度:unrecognized selector sent to instance