使用BASH将CVS diff的结果整理到一个文件中

时间:2014-07-15 10:21:07

标签: bash cvs

我正在尝试更改我的bash脚本,以便将所有更改放在每个文件下,而不是重复相同的文件名。

所以我正在使用这个命令做差异:

grep Index ${logs}/${file_diff} | cvs -q diff -r $pTag $pathDir | sed -r 's/^.+\///' > ${logs}/${output_filename}

以上内容将在output_filename中显示上一个标记中的更改结果。但问题在于pathDir

pathDir在相同的文件中有变化,但每个主题的路径不同:

所以pathDir包含

的路径
this/is/the/path/to/the/changes/for/apples

this/is/the/path/to/the/changes/for/bananas

this/is/the/path/to/the/changes/for/grapes

但在这些路径中,文件名change.dat具有所有更改。

无论如何,我可以更改grep以显示仅在change.dat下的苹果,香蕉和葡萄的所有更改?

目前它将更改显示为:

this/is/the/path/to/the/changes/for/apples/change.dat

{Apple changes here}

this/is/the/path/to/the/changes/for/bananas/change.dat

{Banana changes here}

this/is/the/path/to/the/changes/for/grapes/change.dat

{Grape changes here}

因为更改在change.dat中我想合并它们只显示change.dat中的更改。

谢谢,

1 个答案:

答案 0 :(得分:0)

#!/bin/bash
# the above shebang line MUST be #!/bin/bash, since we use features not in /bin/sh

exec 3>/dev/null                        # start out with FD 3 writing to /dev/null
while read -r; do                       # iterate over lines in the cvs diff
  if [[ $REPLY = "Index: "* ]]; then    # when we see a line starting with "Index: "...
    full_filename=${REPLY%"Index: "}    # ...extract the filename
    base_filename=${full_filename##*/}  # ...then extract only the basename
    exec 3>>"$base_filename"            # ...then open FD 3 to append to the basename
    printf '%s\n' "$REPLY" >&3          # ...then write the index line itself
  else                                  # for lines that don't start with "Index: "...
    printf '%s\n' "$REPLY" >&3          # ...write the line to the existing FD3
  fi
done < <(cvs -q diff -r "$pTag" "$pathDir") # do the above for the output from cvs diff

这将为每个basename提供一个输出文件 - 运行此脚本时当前工作目录中的change.dat将包含存储库中每个change.dat的更改,以及其中的每个其他基本名称存储库将类似地生成不同的输出文件。相反,如果您想忽略任何未命名为change.dat的文件:

#!/bin/bash
# the above shebang line MUST be #!/bin/bash, since we use features not in /bin/sh

while read -r; do                       # iterate over lines in the cvs diff
  if [[ $REPLY = "Index: "* ]]; then    # when we see a line starting with "Index: "...
    full_filename=${REPLY%"Index: "}    # ...extract the filename
    base_filename=${full_filename##*/}  # ...then extract only the basename
  fi
  # print to stdout if and only if the current filename is change.dat
  [[ $base_filename = change.dat ]] && printf '%s\n' "$REPLY"
done < <(cvs -q diff -r "$pTag" "$pathDir") # do the above for the output from cvs diff

有关这种逐行读取输入法的更多信息,请参阅BashFAQ #001

有关上面使用的字符串操作技术的更多信息,请参阅BashFAQ #073;有关bash中字符串操作的更温和介绍,请参阅BashFAQ #100

有关我们如何在此处使用exec的更多信息,请参阅the bash-hackers tutorial on redirection(页面的其他部分也可能是很好的阅读材料)。