用替换合并两个文件

Merging of two files with substitution

我需要合并两个文件,将文件 2 的内容直接添加到文件 1 的末尾。值得注意的是,第一个文件的最后一行包含短语“END”。我需要删除它并在其中添加文件 2 的内容:

文件 1:

string 1
string 2
string N
END

文件 2:

string 3
string 4
string M

应该给我文件3

string 1
string 2
string N
string 3
string 4
string M

我试过简单地使用

cat file1 file2 >> file3

但它没有替换 file2 中的 END。我可以为此使用特殊选项吗?

使用sed:

sed -e '${r file2' -e ';$d;}' file1

string 1
string 2
string N
string 3
string 4
string M

如果您想使用 shell 变量而不是直接使用文件名:

sed -i.bak -e "${r $f2" -e ';$d;}' "$f1"

awk 的方法。它只是!跳过出现在 file1 最后一行的 END 秒。它通过使用辅助变量 set.

识别 file1 的最后一行

file

中使用多个 END 进行测试
% awk 'set==""&&NR!=FNR&&last=="END"{last="";set=1} 
    last!=""{print last} 
    {last=[=10=]} END{print}' file file
string 1
string 2
END
string N
string 1
string 2
END
string N
END

使用 file1file2

% awk 'set==""&&NR!=FNR&&last=="END"{last="";set=1} 
    last!=""{print last} 
    {last=[=11=]} END{print}' file1 file2
string 1
string 2
string N
string 3
string 4
string M

数据

% cat file
string 1
string 2
END
string N
END

% cat file1
string 1
string 2
string N
END

% cat file2
string 3
string 4
string M

假设:

  • file1 只有一个条目标记为 END
  • END 条目在 file1
  • 的末尾

对 OP 当前 cat 想法的小修改,使用流程替换从 file1 中删除 END:

$ cat <(grep -v '^END$' file1) file2 > file3
$ cat file3
string 1
string 2
string N
string 3
string 4
string M

安德烈 awk 解决方案的变体,我们打印我们看到的所有内容 除了 file1/END 条目:

$ awk 'FNR==NR && /^END$/ {next} 1' file1 file2 > file3
$ cat file3
string 1
string 2
string N
string 3
string 4
string M

这可能对你有用(GNU head & cat):

head -n-1 file1 | cat - file2 > file3

读取文件 1 中除最后一行以外的所有内容,并将其与文件 2 连接。

备选方案:

sed -i -e '$r file2' -e '$d' file1

这会将 file2 添加到 file1 的末尾减去 file1 的最后一行,然后用结果替换 file1。

在此处添加 tac + awk 解决方案的 1 个变体以获得乐趣。

tac file1 | awk 'FNR==1{system("tac file2");next} 1' | tac

解释:为以上添加详细解释。

tac file1 |               ##using tac command to read contents from bottom to up and sending its standard output as standard input to awk command here.
awk '                     ##Starting awk program from here.
  FNR==1{                 ##Checking condition if this is first line then do following.
    system("tac file2")   ##Printing file2 bottom to up contents.
    next                  ##next will skip all further contents from here.
  }
  1                       ##Printing rest of lines(passed from tac file1) here.
' | tac                   ##Reversing order again to make it into original order.