我陷入了文本文件处理的困境,这就是我想要做的。
我使用脚本生成了一个 git 补丁文件,该补丁文件很大,并且许多更改仅在注释中,我将大补丁文件拆分为my/patch/folder
using splitdiff
,然后我使用find
检查每个拆分补丁,看看更改是否在注释中仅有的。我创建了一个单独的 shell 脚本来检查评论:
comments.sh
#!/bin/bash
file=$1
cat $file | grep ^+ | grep -v ^+++ | tr -d " " | tr -d "\t" | cut -c2-3 | while read -r line ; do
if [ $line != "//" ] ; then
exit 0
fi
done
cat $file | grep ^- | grep -v ^--- | tr -d " " | tr -d "\t" | cut -c2-3 | while read -r line ; do
if [ $line != "//" ] ; then
exit 0
fi
done
exit 1
我想使用这个脚本来检查所有更改的行是否都是这样+// this is comment
,所以我知道更改仅在注释中
然后我运行下面的脚本:
#!/bin/bash
rm -f small.patch
touch small.patch
find my/patch/folder -type f
-print0 | xargs -0 sh -c '
for i
do
./comments.sh "$i"
[ $? -eq 0 ] && cat "$i" >> small.patch
done
' _
但退出代码似乎./comments.sh "$i"
总是 1,我不知道为什么,我最终创建了相同的大补丁文件
请帮忙,谢谢!
答案1
一些初步的想法。
与使用 say 相比,使用while read
循环会很慢grep -qv '//'
cat | grep | grep | TR | cut |grep
与仅使用相比会很慢sed
。
如果没有实际数据,很难判断您的问题是什么。因此,让我们改变问题,找出任何易于测试的替代方案。
显然,由于我没有你的数据,所以我没有对此进行测试。
因此,让我们创建一个新的 noncomments.sh 脚本。这将返回非注释行。这应该很容易测试,在任何补丁文件上运行它并查看它吐出哪些非注释行。
#!/bin/sh
# delete the +++ and --- lines from unified diff. remove lines which are not
# added/removed. remove added/removed lines which are comments or blank
# output anything that is left
sed '/^+++/d;/^---/d;/^[+-]/!d;/^.[ \t]*\/\//d;/^.[ \t]*$/d' "$@"
然后把它们绑在一起
#!/bin/bash
find my/patch/folder -type f
-print0 | xargs -0 sh -c '
for i
do
[ -z "$(./noncomments.sh "$i")" ] || cat "$i"
done
' > small.patch
这只会重定向一次。
可以稍微改变工作的平衡,例如,如果仅更改注释,则使脚本不输出任何内容;如果没有注释更改,则使脚本输出整个文件。那么命令就是
find my/patch/folder -type f -exec ./noncommentchanges {} \; > small.patch
答案2
这些场景基本上是我们对以下内容做出的一组断言:git差异数据。而且,每当我们听到断言时,我们就会伸手去寻求环顾四周,例如,他们在珀尔正则表达式引擎。
find my/patch/folder -type f \
-exec perl -lne '
tr/ \t//dr =~
m{(?=^[-+])(?!^([-+])\1{2})(?=^.(?!//))}
and exit 0}{exit 1
' {} \; -exec cat {} + > small.patch
研究正则表达式:
# delete indiscriminately all spaces n TABs
tr/ \t//dr =~
m{ (?# From where I stand...)
(?=^[-+]) (?# I can see the beginning of line to my immediate eight followed by either a plus or minus sign)
### AND ###
(?!([-+])\1{2}) (?# I donot see --- or +++ string at the beginning of line)
###:AND ###
(?=.(?!//)) (# I donot see // as the 2nd and 3rd characters)
}x;
## so when all 3 assertions are met,
can we say that we have seen a
noncomment commit line and so we
promptly exit with a Unixy success (0)
else we wait till the eof to exit with a
Unixy failure (1)