使用 sed 将一个文件的内容复制到另一个文件

使用 sed 将一个文件的内容复制到另一个文件

我想在 Alma Linux 8 上使用 sed 将一个文件中的所有文本复制到另一个文件中。例如,第一个文件old.txt是:

192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4
192.168.0.5 
...

另一个文件new.txt是:

192.168.0.1
192.168.0.2
192.168.0.3

我想将条目复制到old.txtnew.txt不重复。预期产出new.txt

192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4
192.168.0.5 

我怎样才能做到这一点?

答案1

除了具有唯一性约束的简单排序之外不需要任何东西。

sort -u old.txt new.txt >new.txt.tmp &&
     mv -f new.txt.tmp new.txt
rm -f new.txt.tmp

我看到POSIXsort确实定义了能力直接写入输入文件,所以你也可以这样做,但我还没有测试过它在发生故障时的鲁棒性如何(以前的版本保证要么保留原来的,要么用新的替换它,不会造成损失):

sort -o new.txt -u old.txt new.txt

或者你可以使用awk.此版本保持文件中行的顺序不变,从第一个文件开始,仅添加后续文件中的新行:

awk '
    FNR<NR && h[$0] { next }    # Skip seen lines in secondary files
    { h[$0]=1; print }          # Record the line and output it
' new.txt old.txt

我已将其分成几行,以便我可以添加评论。删除它们,您可能会将其崩溃为一行,但通常最好编写可读的代码。它故意不删除第一个文件new.txt.如果你想要那个,

awk '! h[$0]++' new.txt old.txt

这会增加所看到的每一行的关联数组值,但仅当该值为零(未设置)时才打印它。

答案2

根据其他答案,您可以使用sort命令,但您可以明确提及输出文件并就地进行排序(没有中间文件)

sort -u -o new.txt old.txt new.txt  

可能的方法之一awk

awk -i inplace '{z[$0]=1} END{for( i in z) print i}' new.txt old.txt

请注意,如果一个或两个输入文件很长,这可能会“吃掉”大量内存。inplace将保持输出new.txt

答案3

这并不是真正的工作sed,但如果你必须使用sed并且你sed恰好是 GNU sed,你可以这样做:

sed -E '
  :1; $!{N;b1}
  :2; s/^((.*)$(.|\n)*)\n\2$/\1/m; t2
  ' new.txt old.txt

在哪里:

  • :1; $!{N;b1}在循环中加载整个输入(模式空间中的两个文件)。
  • :2; s/^((.*)$(.|\n)*)\n\1$/\1/m; t2在循环中删除该模式空间中的重复行。

new.txt就地修改,您可以执行以下操作:

sed -nE '
  :1; $!{N;b1}
  :2; s/^((.*)$(.|\n)*)\n\1$/\1/m; t2
  w new.txt
  ' new.txt old.txt

答案4

使用(以前称为 Perl_6)

~$ raku -e '.put for lines.unique;'  old.txt new.txt  > tmp.txt

Raku 将使用主力例程从命令行读取文件lines。因此可以读入两个文件,并将>其重定向到一个tmp.txt文件中。然后,一旦验证结果,您就可以将tmp.txt文件复制回来new.txt

Raku 不进行“就地”编辑(即,Raku 中没有相当于 Perl-i命令行标志的功能)。

输入示例old.txt

192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4
192.168.0.5 

输入示例new.txt

192.168.0.1
192.168.0.2
192.168.0.3

示例输出tmp.txt

192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4
192.168.0.5 

Raku 例程的一个优点unique是它带有一个as参数,这意味着在比较中仅使用输入行的一部分unique。这样的选项允许(例如)从完整路径恢复唯一的文件名,丢弃不同目录中的重复名称。有关详细信息,请参阅下面的第一个 SO 链接。

https://unix.stackexchange.com/a/720574/227738
https://docs.raku.org/routine/unique
https://raku.org

相关内容