两个文件的增量合并bash+;雨衣

两个文件的增量合并bash+;雨衣,bash,macos,merge,Bash,Macos,Merge,我想按以下规则逐行合并两个文件: 文件2-是最新的英文版本; 文件1-以前的翻译版本 文件1 文件2 我想将它们合并到结果文件(file1)中,如下所示 foo_11: "Марія" foo_112: "Superman" FOOTLONG: "Subway" foo_13: "Юлія" 即,如果行的第一部分没有更改,则整行保持不变。如果第一部分已更改或不存在,则应添加整行或替换以前的版本。我只想在文件1中添加新的行,最好标记一些被更改的行,例如foo_12 换句话说,我需要git合并,但

我想按以下规则逐行合并两个文件:

文件2-是最新的英文版本; 文件1-以前的翻译版本

文件1

文件2

我想将它们合并到结果文件(file1)中,如下所示

foo_11: "Марія"
foo_112: "Superman"
FOOTLONG: "Subway"
foo_13: "Юлія"
即,如果行的第一部分没有更改,则整行保持不变。如果第一部分已更改或不存在,则应添加整行或替换以前的版本。我只想在文件1中添加新的行,最好标记一些被更改的行,例如foo_12

换句话说,我需要git合并,但由于文件只是部分相同,我不确定如何实现这一点

我正试图在Mac bash中实现这一点。 谢谢


UPD:可以使用
连接来完成繁重的工作(需要输入已经排序):

这给了你:

foo_11: "Марія" "Maria"
foo_112: "Superman"
FOOTLONG: "Subway"
foo_13: "Юлія" "Julia"
从这里可以很简单地删除第三列:

join -a2 file1 file2 | cut -d'"' -f1-3
如果输入已经排序,或者按需对其进行排序,并且可以选择按排序顺序输出结果,则中使用的
join
值得考虑

awk
解决方案:

  • 不需要对输入文件进行排序
  • 在输出中保留
    file2
    的输入顺序
  • 用尾随的
    *
删除
#
以实际使用输出更新
文件1

这会将
file1
行存储在一个关联数组中,该数组的键首先是基于
的第一个字段:
,然后按如下方式处理
file2

  • 如果在
    file1
    中找到了第一个字段,则从
    file1
    输出行(现有翻译)
  • 否则,从
    file2
    输出该行,并附加一个
    *
    ,以指示该行是
    file2
    的新行(需要翻译的新行)
    • 在awk中:

      $ awk 'NR==FNR { a[$1]=$2; next } 
                     { print $1, (a[$1]?a[$1]:$2) }
      ' file1 file2
      foo_11: "Марія"
      foo_112: "Superman"
      FOOTLONG: "Subway"
      foo_13: "Юлія"
      

      抱歉,忘了添加,排序应该与原始排序保持一致(实际上它没有排序)。@AlCrow:在其当前形式中,答案仅与第一个
      (字段
      $1
      )之前的所有行匹配。行的其余部分是否包含其他
      实例并不重要。我不知道你在问什么;如果您的目的是扩展原始需求,我建议您创建一个新问题。谢谢!这正是我想要的。现在,如何跟踪第二部分中的更改(在第一部分之后):
?我想现在我们必须使用两个英文版本。第二部分也可能包含另一个
(在引号
内)。如果在英文文件中发现差异,则必须以相同的方式更新翻译。ThnxOK,对不起,我增加了复杂性。然后我将创建另一个线程。@AlCrow:听起来不错;我建议你从你的新问题链接到这个问题。或者我不需要它。只是考虑添加一个分隔符,例如
然后使用您的方法捕获两个英文版本中的更改,然后将结果文件与翻译后的文件进行比较。你觉得怎么样?
foo_11: "Марія" "Maria"
foo_112: "Superman"
FOOTLONG: "Subway"
foo_13: "Юлія" "Julia"
join -a2 file1 file2 | cut -d'"' -f1-3
awk -F':' '
  FNR==NR { seen[$1]=$0; next } 
  $1 in seen { print seen[$1]; next}
  { print $0 "*" }
' file1 file2 # > file1.tmp && mv file1.tmp file1
$ awk 'NR==FNR { a[$1]=$2; next } 
               { print $1, (a[$1]?a[$1]:$2) }
' file1 file2
foo_11: "Марія"
foo_112: "Superman"
FOOTLONG: "Subway"
foo_13: "Юлія"