使用bash将从文本文件中删除的行复制回其原始文件中



在GitHub存储库中,我有大约一百个自动生成的文件,其中有一个注释头,用于指定生成日期、版本等内容。

问题是,通常情况下,头会更改,但文件的实际有用内容不会更改。当这种情况发生时,GitHub报告了大约一百个更改的文件,而实际上可能只有几个更改了。这使得我们很难发现真正的变化。

不幸的是,由于与当前问题无关的原因,这些标头必须在发布时出现。否则,我会把它们脱光,就这样算了。

为了解决这个问题,我的计划是:

  1. 在将注释头提交到存储库之前,将其从文件中剥离并保存到一个单独的文件中
  2. 作为Jenkins管道中的一步,在发布时将头重新组合到文件中

对于计划的第一部分,我将剥离文件的前5行,并将它们保存到一个单独的versions.txt文件中。

我正在处理的原始文件(*.h(都有类似的格式

/* Some comment */
/* More useless text */
/* Version of the file */
/* Maybe a date */
/* More comment */
Actual useful file content

我使用以下命令

head -5 *.h > versions.txt && sed -i '1,+4d' *.h

从每个文件中删除前5行,并创建一个versions.txt文件,最终看起来像这样:

==> File1.h <==
/* Some comment */
/* More useless text */
/* Version of the file */
/* Maybe a date */
/* More comment */
==> File2.h <==
/* Some comment */
/* More useless text */
/* Version of the file */
/* Maybe a date */
/* More comment */
==> File3.h <==
/* Some comment */
/* More useless text */
/* Version of the file */
/* Maybe a date */
/* More comment */

我现在想找到一种方法来恢复这个过程,并将每组行放回各自的原始文件中。

一个更好的选择是让GitHub忽略文件的前5行,但据我所知,这是不可能的。

试试这个解决方案:

awk '/^==>/ { cnt=1;filname=$2 } { print "sed -i ""cnt"i "$0"" "filname;cnt++ }' version.txt

这种对以"==>quot;并将所述第二空格分隔字段设置为变量filtname。这一过程一直排到下一个"==>quot;然后用于创建一个sed命令,在文件顶部插入行,使用cnt来terack文件中插入行的位置。

一旦你对上面的命令按预期打印sed命令感到满意(非常重要!(,你就可以用awk的系统功能操作命令,所以:

awk '/^==>/ { cnt=1;filname=$2 } { system("sed -i ""cnt"i "$0"" "filname);cnt++ }' version.txt

Raman Sailopal的回答切中要害,除了几个细节:

  1. 该命令还将插入剥离命令head -5 *.h > versions.txt && sed -i '1,+4d' *.h生成的==> Filename <==
  2. 该命令不会插入空行
  3. 该命令用于原始剥离命令插入的额外空行,作为文件之间的分隔符

因此,我用if语句扩展了提供的命令,使其

  1. 仅在cnt > 1 && cnt < 7使其仅在五行上工作时工作,而忽略第一行==> Filename <==
  2. 根据需要插入带有sed -i 1G的空行。以下是我最终得到的完整命令:
awk '/^==>/ { cnt=1;filename=$2 } 
{ if(cnt > 1 && cnt < 7 && $0 == "") system("sed -i ""cnt-1"G" " filename)} 
{ if(cnt > 1 && cnt < 7 && $0 != "") system("sed -i ""cnt-1"i "$0"" "filename);cnt++}' versions.txt