我正在尝试更改我的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
中的更改。
谢谢,
答案 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(页面的其他部分也可能是很好的阅读材料)。