查找并读取文件中的行然后检查注释行

查找并读取文件中的行然后检查注释行

我陷入了文本文件处理的困境,这就是我想要做的。

我使用脚本生成了一个 git 补丁文件,该补丁文件很大,并且许多更改仅在注释中,我将大补丁文件拆分为my/patch/folderusing 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)

相关内容